Skip to content

fix: prevent false positive auto-shrink when window is hidden#335

Open
karry-0803 wants to merge 9 commits into
TouchAI-org:mainfrom
karry-0803:fix/auto-shrink-hidden-state
Open

fix: prevent false positive auto-shrink when window is hidden#335
karry-0803 wants to merge 9 commits into
TouchAI-org:mainfrom
karry-0803:fix/auto-shrink-hidden-state

Conversation

@karry-0803

@karry-0803 karry-0803 commented May 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes a bug where the window would incorrectly auto-shrink even if the user hadn't read the latest message before hiding the window.

When the window is minimized or sent to the tray, its clientHeight becomes 0. The isScrolledToBottom logic (scrollHeight - scrollTop - clientHeight < 5) would then produce a false positive, incorrectly marking the unread message as "seen" while the window was hidden. This PR adds defensive checks to ensure clientHeight > 0 before updating the latestContentVisibility state, and completely blocks visibility updates when the container is hidden, ensuring the read marker is strictly bound to actual visual exposure.

Related issue or RFC

Follow-up fix for [Feature]: adjust window auto-shrink timing based on session state, read state, and inactivity #245

AI assistance disclosure

  • Tool(s) used: GPT-based coding assistant
  • Scope of assistance: Bug root cause analysis, code logic fixes, testing validation, and PR drafting.
  • Human review or rewrite performed: I reviewed all affected files, verified the logical fix for clientHeight checks, and tested the final behavior locally before pushing.
  • Architecture or boundary impact: No architecture or cross-boundary changes intended. Only local state calculations in the view component were patched.

Testing evidence

Tested locally: Reopening the window from the tray after a 5+ minute timeout while the latest message is unread correctly keeps the window expanded.

pnpm --filter @touchai/desktop test:unit passed locally.
Relying on CI for pnpm test:pr and full suite confirmation.

Did you follow TDD (test-first) for feature and fix work? Strongly recommended.
No, this was a targeted bug fix for a view-layer calculation edge case.

Risk notes

  • AgentService, runtime, MCP, or schema impact: none
  • database baseline or migration impact: none
  • release or packaging impact: none

Screenshots or recordings

Reopened from tray after 5+ minutes. The window correctly remains expanded because the scrollbar was not at the bottom before hiding.

测试5

Checklist

  • The PR title follows Conventional Commits and is valid for squash merge.
  • This PR is either ready for review or explicitly marked as a Draft PR.
  • I did not use [WIP] or similar title prefixes.
  • If AI materially assisted this PR, I disclosed the tools and scope and I personally reviewed every affected change.
  • I can explain the why, what, and how of this change without relying on an AI tool.
  • If this touches AgentService, runtime, MCP, or schema boundaries, there is an accepted RFC.
  • If this changes architecture or adds a new cross-boundary abstraction, there is an accepted RFC.
  • I ran pnpm test:pr for this code PR, or this is a docs-only change.
  • If I changed Rust behavior or tests, I reviewed pnpm test:coverage:rust or relied on CI coverage evidence.
  • If I changed desktop startup/window/search/popup/settings/E2E paths, I ran pnpm test:e2e locally or documented why CI is the first valid proof. (Relying on CI for E2E since this is a pure UI state fix and CI provides an isolated environment).
  • I added tests or explained why tests are not appropriate. (Existing tests cover auto-shrink logic, this fix patches a DOM height edge case that is hard to unit test but verified manually).
  • I updated docs when behavior changed.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @karry-0803, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@github-actions github-actions Bot added the area:frontend Frontend UI or view-layer changes label May 31, 2026
@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

ConversationPanel removes the ConversationToolbar and its wiring, replaces toolbar-centric emits with panel-level and kebab-case events, tightens scroll/visibility guards for missing or zero-height containers, exposes timeline scrollToBottom, forces getHistoryAnchor() -> null, and centralizes scroll-to-bottom visibility with a ResizeObserver-driven flow.

Changes

ConversationPanel toolbar removal and API refactoring

Layer / File(s) Summary
Template structure and toolbar removal
apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue
Template root wrapper is adjusted and ConversationToolbar is removed; a timelineRef is added and toolbar-related imports are dropped.
ConversationTimeline expose
apps/desktop/src/views/SearchView/components/ConversationPanel/components/ConversationTimeline.vue
Remove leading BOM and add/expose scrollToBottom() which sets activeMarkerId to the last user message id.
Event and visibility contract updates
apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue
defineEmits replaced toolbar-centric camelCase events with kebab-case equivalents and new panel-level events (focus, dismiss, clearSession, openSettings, togglePin, toggleMaximize); visibility helpers now early-return for missing/hidden/zero-height containers.
Scroll handler updates
apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue
handleScroll, syncToBottom, and smoothScrollToBottom now refresh and emit latest-content visibility after scroll changes.
Refresh logic, ResizeObserver, and exposed API
apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue
Centralize refreshScrollToBottomVisibility(), update timeline jump/regenerate/auto-scroll handlers, force getHistoryAnchor() to return null, adjust defineExpose set, and wire a ResizeObserver on the message list for auto-scroll/visibility updates.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • hiqiancheng

"A rabbit hops through code with delight,
Toolbar is gone — the panel takes flight,
ResizeObserver watches, keeping scrolls tight,
Emits now whisper in kebab-case tonight,
Tiny paws update the timeline's bright light." 🐇✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The PR title 'fix: prevent false positive auto-shrink when window is hidden' follows Conventional Commits format with 'fix' prefix, clearly describes the bug fix addressing the core issue, and is concise and appropriate for the changeset.
Description check ✅ Passed The PR description is comprehensive and follows the required template with all major sections filled out: Summary, Related issue, AI assistance disclosure, Testing evidence, Risk notes, Screenshots, and Checklist completed.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot requested a review from hiqiancheng May 31, 2026 06:36

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue (1)

317-327: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

refreshScrollToBottomVisibility() now causes duplicate latestContentVisibilityChange emits.

This helper now emits visibility itself, but callers still emit after invoking it, causing duplicated events and redundant downstream side effects. Keep emission in one place only.

Minimal fix (keep existing caller contracts)
 function refreshScrollToBottomVisibility() {
     if (!conversationContainer.value) {
         showScrollToBottom.value = false;
         return;
     }

     const atBottom = isScrolledToBottom(conversationContainer.value);
     showScrollToBottom.value = hasScrollbar() && !atBottom;
-
-    emitLatestContentVisibility();
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue`
around lines 317 - 327, The helper refreshScrollToBottomVisibility currently
calls emitLatestContentVisibility(), causing duplicate
latestContentVisibilityChange events because callers also emit after calling it;
remove the internal emitLatestContentVisibility() call from
refreshScrollToBottomVisibility so that only callers (who already emit) are
responsible for emitting, keeping caller contracts unchanged; search for
refreshScrollToBottomVisibility and emitLatestContentVisibility to locate and
update the function.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/package.json`:
- Around line 59-64: Remove the runtime dependency entry for "`@types/dompurify`"
from package.json (either delete it or move it to devDependencies) because
DOMPurify 3.x ships its own types, and update the pinned "dompurify": "3.4.2"
entry to a current 3.x patch (e.g. "^3.4.7" or "^3.4.x") to pick up downstream
fixes; ensure you update package.json entries for "`@types/dompurify`" and
"dompurify" accordingly and run the package manager install to update lockfiles.

---

Outside diff comments:
In `@apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue`:
- Around line 317-327: The helper refreshScrollToBottomVisibility currently
calls emitLatestContentVisibility(), causing duplicate
latestContentVisibilityChange events because callers also emit after calling it;
remove the internal emitLatestContentVisibility() call from
refreshScrollToBottomVisibility so that only callers (who already emit) are
responsible for emitting, keeping caller contracts unchanged; search for
refreshScrollToBottomVisibility and emitLatestContentVisibility to locate and
update the function.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fe871742-163b-4d01-bd24-a2abc51c8a56

📥 Commits

Reviewing files that changed from the base of the PR and between f0bd14d and 4052827.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • apps/desktop/package.json
  • apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Rust Checks
  • GitHub Check: Frontend Tests
  • GitHub Check: Frontend Quality
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (rust)
  • GitHub Check: Desktop E2E Smoke (Windows)
🔇 Additional comments (1)
apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue (1)

196-200: LGTM!

Also applies to: 229-235

Comment thread apps/desktop/package.json Outdated
@karry-0803 karry-0803 force-pushed the fix/auto-shrink-hidden-state branch from 4052827 to 0be00bb Compare May 31, 2026 07:51
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 31, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue`:
- Line 27: The template has a malformed event binding on the MessageItem
component: replace the broken fragment '`@regenerate`=handleRegenerateMessage as
any)"' with a proper Vue event binding such as
`@regenerate`="handleRegenerateMessage" (or `@regenerate`="(e) =>
handleRegenerateMessage(e)" if you need the event), keeping the
:message="message" prop; fix the syntax around the MessageItem usage so the
component tag compiles (reference: MessageItem and handleRegenerateMessage).
- Around line 276-279: The computed definition for outputScrollBehavior is
broken by a misplaced line break and an extra "l);" token; fix the computed call
by declaring outputScrollBehavior = computed(() => (useSettingsStore() as
any).preferences.behavior.outputScroll) so the arrow function and parentheses
are correctly paired and remove the stray "l);". Locate the outputScrollBehavior
declaration and correct the syntax around computed, the arrow function, and the
closing parentheses so the expression is a single well-formed computed call.
- Around line 237-245: The function handleTimelineJump contains a broken
optional-chained tagged template: the querySelector call is split across lines
producing an invalid tagged template expression; fix it by calling
conversationContainer.value?.querySelector with a single template-string
argument (e.g.
conversationContainer.value?.querySelector(`[data-message-id="${messageId}"]`)
), removing the stray backticks and stray parentheses so the element lookup and
subsequent element.scrollIntoView and markUserScrollIntent() operate on the
properly retrieved element.
- Around line 58-71: The import statements in ConversationPanel (references:
AppIcon, computed, nextTick, onMounted, onUnmounted, ref, useSettingsStore,
SessionMessage, ConversationTimeline, MessageItem) are malformed (missing the
leading "i" on "import", split keywords and extra commas), causing parse
failures; fix by restoring each to a single, valid ES import line (e.g., "import
..." for AppIcon and components, and a single import from 'vue' that lists
computed,nextTick,onMounted,onUnmounted,ref without duplicate commas or line
breaks, plus correct imports for useSettingsStore and SessionMessage) so all
symbols are imported with proper syntax.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 21f64743-a379-43d4-a680-9715134351aa

📥 Commits

Reviewing files that changed from the base of the PR and between 0be00bb and 2c07ea8.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: CodeQL (rust)
  • GitHub Check: Frontend Tests
  • GitHub Check: Rust Checks
  • GitHub Check: Desktop E2E Smoke (Windows)
🧰 Additional context used
🪛 Biome (2.4.15)
apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue

[error] 58-58: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 58-58: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 58-58: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 60-60: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 60-60: Expected an expression but instead found ','.

(parse)


[error] 60-60: Expected an expression but instead found ','.

(parse)


[error] 60-60: Expected an expression but instead found ','.

(parse)


[error] 60-60: Expected an expression but instead found ','.

(parse)


[error] 60-60: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 65-65: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 65-65: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 65-65: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 70-70: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 70-70: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 70-70: Expected a semicolon or an implicit semicolon after a statement, but found none

(parse)


[error] 238-239: Tagged template expressions are not permitted in an optional chain.

(parse)


[error] 240-335: unterminated template literal

(parse)


[error] 335-335: expected } but instead the file ends

(parse)

🔇 Additional comments (3)
apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue (3)

119-140: The visibility guard logic correctly addresses the PR objective.

The defensive checks for clientHeight === 0 in emitLatestContentVisibility() (line 122) and isScrolledToBottom() (line 134) properly prevent false positives when the window is hidden. When the container is minimized or sent to tray, clientHeight becomes 0, and these guards ensure the read marker state is preserved rather than incorrectly updated.

LGTM!


255-257: Verify that all call sites of ConversationPanel’s getHistoryAnchor() safely handle the null return.

apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue now exposes getHistoryAnchor() that returns null unconditionally (lines 255-257). Callers must guard for null and provide an appropriate fallback before using the returned element.


281-283: Potential accessibility regression: ConversationPanel exposed focus() only emits focus (may no longer move DOM focus).

apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue (281-283) has function focus() { emit('focus'); }, but apps/desktop/src/views/SearchView/index.vue and apps/desktop/src/views/SearchView/composables/useSearchPage.ts call conversationPanel.value?.focus();. Ensure the call chain actually results in focus moving to the intended element (e.g., via @focus/v-on:focus handlers that set DOM focus, or by keeping the exposed focus() implementation focused on conversationContainer).

Comment thread apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue Outdated
Comment thread apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue Outdated
Comment thread apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue Outdated
@karry-0803 karry-0803 force-pushed the fix/auto-shrink-hidden-state branch from ef0024c to 9f30677 Compare May 31, 2026 09:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue (3)

108-111: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve the existing ConversationPanelHandle contract.

apps/desktop/src/views/SearchView/types.ts:62-68 still requires isLatestContentVisible(), and the handle is still modeled as imperative. Dropping that method from defineExpose() and turning focus() into an event emit means ref-based callers can get undefined or a silent no-op.

💡 Minimal compatibility fix
 function focus() {
-    emit('focus');
+    conversationContainer.value?.focus();
 }

 // 暴露方法给父组件
 defineExpose({
     focus,
     revealLatestContent,
     scrollByDelta,
     getHistoryAnchor,
+    isLatestContentVisible,
 });

Also applies to: 273-275, 321-326

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue`
around lines 108 - 111, The ConversationPanel must preserve the imperative
ConversationPanelHandle contract: re-add isLatestContentVisible() to the object
passed to defineExpose() (implement using the existing isLatestContentVisible
function) and keep focus() exposed as a method rather than replacing it with an
event emit so ref-based callers continue to work; update every defineExpose call
in this component (including the other occurrences around the focus-related
changes you modified at the other spots) to return an object matching
ConversationPanelHandle with isLatestContentVisible and focus methods.

32-39: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Bind timelineRef in the template.

revealLatestContent() relies on timelineRef.value?.scrollToBottom() when the container is already at the bottom, but <ConversationTimeline> never assigns that ref. That makes the parent’s post-open revealLatestContent() path a silent no-op.

💡 Suggested fix
             <ConversationTimeline
+                ref="timelineRef"
                 :messages="messages"
                 :container-height="maxHeight"
                 :scroll-top="scrollTop"
                 :scroll-height="scrollHeight"
                 :client-height="clientHeight"

Also applies to: 254-256, 277-288

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue`
around lines 32 - 39, The ConversationTimeline component is not bound to the
parent timelineRef, so revealLatestContent() cannot call
timelineRef.value?.scrollToBottom(); fix by adding the template ref binding to
the ConversationTimeline elements (e.g., add ref="timelineRef" on the
<ConversationTimeline .../> instances) so the timelineRef defined in setup is
assigned and revealLatestContent, timelineRef.value.scrollToBottom(), and
related handlers (revealLatestContent, handleTimelineJump) work correctly; apply
the same ref binding to the other ConversationTimeline usages mentioned.

90-99: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep the emitted event API compatible with the current parent wiring.

SearchView still listens for pin-change, maximize-toggle, new-session, history-open-change, history-prefetch, drag-start, and drag-end in apps/desktop/src/views/SearchView/index.vue:1296-1314. Replacing the contract here without migrating that parent in the same change drops those interactions end-to-end.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue`
around lines 90 - 99, The component replaced its emitted event contract (defined
in defineEmits) and broke parent wiring; restore backward compatibility by
adding the legacy event names back (or emit both new and legacy names) so
SearchView continues to receive pin-change, maximize-toggle, new-session,
history-open-change, history-prefetch, drag-start, and drag-end; update the
defineEmits declaration to include these string event signatures alongside the
new ones (or ensure that methods like togglePin, toggleMaximize, clearSession,
latestContentVisibilityChange also emit the legacy event names) so existing
parent listeners in SearchView keep working.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue`:
- Around line 108-111: The ConversationPanel must preserve the imperative
ConversationPanelHandle contract: re-add isLatestContentVisible() to the object
passed to defineExpose() (implement using the existing isLatestContentVisible
function) and keep focus() exposed as a method rather than replacing it with an
event emit so ref-based callers continue to work; update every defineExpose call
in this component (including the other occurrences around the focus-related
changes you modified at the other spots) to return an object matching
ConversationPanelHandle with isLatestContentVisible and focus methods.
- Around line 32-39: The ConversationTimeline component is not bound to the
parent timelineRef, so revealLatestContent() cannot call
timelineRef.value?.scrollToBottom(); fix by adding the template ref binding to
the ConversationTimeline elements (e.g., add ref="timelineRef" on the
<ConversationTimeline .../> instances) so the timelineRef defined in setup is
assigned and revealLatestContent, timelineRef.value.scrollToBottom(), and
related handlers (revealLatestContent, handleTimelineJump) work correctly; apply
the same ref binding to the other ConversationTimeline usages mentioned.
- Around line 90-99: The component replaced its emitted event contract (defined
in defineEmits) and broke parent wiring; restore backward compatibility by
adding the legacy event names back (or emit both new and legacy names) so
SearchView continues to receive pin-change, maximize-toggle, new-session,
history-open-change, history-prefetch, drag-start, and drag-end; update the
defineEmits declaration to include these string event signatures alongside the
new ones (or ensure that methods like togglePin, toggleMaximize, clearSession,
latestContentVisibilityChange also emit the legacy event names) so existing
parent listeners in SearchView keep working.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1b06d70e-7dde-4da9-acf7-ef1390b24921

📥 Commits

Reviewing files that changed from the base of the PR and between 2c07ea8 and 9f30677.

📒 Files selected for processing (1)
  • apps/desktop/src/views/SearchView/components/ConversationPanel/index.vue
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: CodeQL (rust)
  • GitHub Check: CodeQL (javascript-typescript)
  • GitHub Check: Frontend Tests
  • GitHub Check: Rust Checks
  • GitHub Check: Frontend Quality
  • GitHub Check: Desktop E2E Smoke (Windows)

@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@karry-0803

Copy link
Copy Markdown
Contributor Author

@coderabbitai resolve

@coderabbitai

coderabbitai Bot commented May 31, 2026

Copy link
Copy Markdown
✅ Actions performed

Comments resolved and changes approved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:frontend Frontend UI or view-layer changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant