Duck.Ai/ChatHistory: Add context menu - #9760
karlenDimla merged 7 commits into
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
c0ea2e3 to
3165abd
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 3165abd. Configure here.
malmstein
left a comment
There was a problem hiding this comment.
lgtm, one suggestion: the new chat-tab vs new-tab branch has no test, and ChatHistoryViewModelTest already has the pattern for it.
| controls.update { it.copy(mode = Mode.Selecting(emptySet())) } | ||
| } | ||
|
|
||
| fun onChatsProtectionClicked() { |
There was a problem hiding this comment.
suggestion: the inNewTab decision here isn't covered, and the fixture is already in place since FakeDuckChatInternal stubs getChatProtectionUrl. two cases worth pinning with the existing navigationEvents pattern: selected tab is a duck.ai chat so we reuse it, and anything else so we open a new one.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes test module compilation broken when getChatProtectionUrl was added to the DuckChatInternal interface without updating the test fake. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
reduce() stays on Empty when there are no chats, so entering select mode from the empty state was a no-op. Only offer Select Chats when chats are present; Chat Protection remains available regardless. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cover both branches: reuse the current tab when it is a duck.ai chat, open a new tab otherwise. Make FakeDuckChatInternal.isDuckChatUrl match duck.ai hosts so the reuse branch is reachable. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6c82012 to
577a8ee
Compare
1f24033 to
b58e76e
Compare
…9761) Task/Issue URL: https://app.asana.com/1/137249556945/task/1218238186970934?focus=true Tech Design URL (if applicable): API Proposals URL(s) (if applicable): ### Description - New "+" plus menu on the omnibar with New Chat, New Voice Chat, New Image (sidebar-only), New Search / New Tab, and New Fire Tab entries. - New Search (the sidebar relabel of "New Tab") opens a regular new tab and auto-surfaces the native input focused on the Search tab; with the flag off the entry stays "New Tab" and behaves as before. - Generalized the onboarding input-screen one-shot into InputScreenLaunchTarget (carries an InputMode instead of a DUCK_AI boolean) so both onboarding (Duck.ai tab) and New Search (Search tab) can drive the initial input mode. ### Steps to test this PR Setup - [x] Internal build installed - [x] Native input / input screen feature is active (native omnibar input widget with the Search / Duck.ai toggle is in use) - [x] Do at least one duck.ai chat - [x] Open the browser on a New Tab Page and focus the omnibar so the "+" plus button is available 1. `nativeDuckAiSidebar` enabled (default) — open the "+" menu - [x] Tap the "+" plus button in the omnibar - [x] The menu entry (with the add-tab icon) reads New Search (not "New Tab") - [x] The New Image entry IS visible 2. nativeDuckAiSidebar enabled — tap New Search - [x] A new tab opens (regular, non-Fire) - [x] The native input widget IS auto-surfaced (keyboard shown), without a manual omnibar tap - [x] The widget opens with the Search tab selected (not Duck.ai) - [x] The input field is empty and ready to type - [x] Typing a query and submitting performs a search (not a Duck.ai chat) 3. `nativeDuckAiSidebar` disabled (via FF Inventory) — open the "+" menu - [x] Tap the "+" plus button in the omnibar - [x] The menu entry reads New Tab (not "New Search") - [x] The New Image entry is NOT visible 4. nativeDuckAiSidebar disabled — tap New Tab - [x] A new tab opens (regular, non-Fire) - [x] The tab lands with the address bar unfocused (native input is NOT force-opened) - [ ] No Search-tab pre-selection behavior occurs (unchanged pre-existing behavior) Regression check - [ ] Duck.ai onboarding: completing the Search-path onboarding still auto-opens the input screen on the Duck.ai (chat) tab - [ ] Custom-AI onboarding still finishes on the Duck.ai (chat) tab - [ ] Focusing the omnibar on an existing tab (no menu action) still opens the input with the default toggle position — SEARCH is not spuriously forced <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches new-tab creation, activity recreate/deferred actions, and native input initial mode; behavior is gated on `nativeDuckAiSidebar` but onboarding Duck.ai landing must stay correct. > > **Overview** > When **native Duck.ai sidebar** is on, the omnibar **+** menu relabels **New Tab** to **New Search**, shows a **New Image** row (action still TODO), and opening that entry starts a regular tab with the native input screen on the **Search** tab—not Duck.ai. > > **Per-tab initial input mode** is threaded through `launchNewTab` → `PendingAction.OpenNewTab` (including bundle round-trip on browser-mode recreate) → `pendingInputModeTargets` / `BrowserTabFragment.inputModeTarget` → `BrowserTabViewModel.consumeInitialInputMode()`, which prefers that one-shot target and still falls back to post-onboarding **Duck.ai** via `OnboardingInputScreenLaunchTarget` in the ViewModel (removed from the fragment). > > Tests cover `InputMode` persistence across pending mode switch and one-shot consumption behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit aabfdda. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
43ffe64
into
feature/karl/duckai-sidebar/re-route
…ckduckgo#9752) Task/Issue URL: https://app.asana.com/1/137249556945/task/1218228567702514?focus=true Tech Design URL (if applicable): API Proposals URL(s) (if applicable): https://app.asana.com/1/137249556945/project/1201462763415876/task/1218312857360677?focus=true ### Description This is the main PR to Implement replace Chat Sidebar with chats history and include all change outlined in the stack: - duckduckgo#9760 - duckduckgo#9761 - duckduckgo#9773 ### Steps to test this PR _nativeDuckAiSidebar enabled, default_ - [x] Open a duck.ai chat - [x] Select the sidebar - [x] Verify that chats history opens _nativeDuckAiSidebar disabled_ - [x] Open a duck.ai chat - [x] Select the sidebar - [ ] Verify that the FE sidebar opens <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes omnibar Duck.ai navigation behind a remote flag; incorrect rollout could send users to the wrong sidebar/history surface, though legacy behavior is preserved when the flag is off. > > **Overview** > **Routes the omnibar Duck.ai sidebar tap through a feature-flagged path** so users with `nativeDuckAiSidebar` enabled open native chat history (`openDuckChatHistory` / `LaunchDuckChatHistory`) instead of the legacy web sidebar JS bridge. > > Adds **`nativeDuckAiSidebar`** to `DuckAiFeatureState`, wired from remote config via new `DuckChatFeature.nativeDuckAiSidebar()` (default internal) in `RealDuckChat`. `BrowserTabFragment` now calls `onDuckChatSidebarButtonPressed()` instead of `openDuckChatSidebar()` directly. > > Also **fixes swapped native actions**: `onCustomizeResponsesClicked` now emits `NativeAction.CUSTOMIZE_RESPONSES` and `openDuckChatSidebar` emits `NativeAction.SIDEBAR` (they were reversed). Unit tests cover the flag branches, history vs sidebar fallback, and the corrected actions. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 577a8ee. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>


Task/Issue URL: https://app.asana.com/1/137249556945/task/1218238186970938?focus=true
Tech Design URL (if applicable):
API Proposals URL(s) (if applicable):
Description
Steps to test this PR
Setup
nativeDuckAiSidebarenabled, defaultnativeDuckAiSidebaron) from a duck.ai chat tabnativeDuckAiSidebardisabled (via FF inventory)Note
Low Risk
UI and navigation-only changes behind an existing feature flag, with unit tests for URL/tab routing; no auth or data-layer changes.
Overview
Adds a toolbar overflow (⋮) menu on native Duck.ai chat history, shown only when
nativeDuckAiSidebaris enabled. The menu offers Select Chats (enters bulk selection; hidden when history isn’t loaded) and Chat Protection.Chat Protection navigates via a new
getChatProtectionUrl()onRealDuckChat(chatProtection=openon the chat URL). The ViewModel opens that URL in the current tab if the user was already on a Duck.ai chat tab, otherwise in a new tab; the fragment wiresOpenChatProtectiontoBrowserNavaccordingly.Overflow is hidden in select mode and during search. Tests cover tab-reuse vs new-tab behavior; the test fake implements
getChatProtectionUrl()andisDuckChatUrlforduck.ai.Reviewed by Cursor Bugbot for commit b58e76e. Bugbot is set up for automated code reviews on this repo. Configure here.