Android/Duckai/Contextual: Add new menu for chats#8885
Conversation
…extualSheetImprovements When the flag is on, the top-bar "+" icon becomes a chats icon shown in both INPUT and WEBVIEW modes. Clicking opens a popup with up to 5 recent chats and a "View all chats" footer (and a "New chat" header in WEBVIEW mode); with no history it falls through to the legacy new-chat action. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…iew all footer Each recent chat row now shows its per-type icon (matching chat suggestions), and the View all chats footer uses ic_open_in_24. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…sized labels Adds a "Recent chats" section header above the chat rows, caps every popup row's title at 3 lines, and ellipsizes with "…" when truncated. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the 5 static PopupMenuItemView slots with an empty container and inflates one row per chat at runtime, so the popup grows naturally with the available history. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…with no recent chats Previously fell through to a new-chat reset; now the user lands on the chat history screen so they can see (or seed) their history. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
366dd80 to
04091d8
Compare
| } | ||
| if (state.recentChats.isEmpty()) { | ||
| onViewAllChatsClicked() | ||
| } else { |
There was a problem hiding this comment.
WEBVIEW chats icon skips new chat
High Severity
With contextualSheetImprovements on, onChatsIconClicked sends users to chat history whenever recentChats is empty. In WEBVIEW mode that list is often empty because the active chat is filtered out, so tapping the toolbar control no longer starts a new chat and instead closes the sheet and opens history.
Reviewed by Cursor Bugbot for commit 04091d8. Configure here.
There was a problem hiding this comment.
This is expected behavior. If the new icon is clicked and there are not any other recent chats, we should show the chat history instead.
…here When the chat currently loaded in the contextual sheet's webview is deleted from another part of the app (chat history, clear-all, fire button), reset the sheet to its initial INPUT state instead of keeping the now-deleted chat. Gated behind contextualSheetImprovements. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6a63080 to
d778585
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ 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 d778585. Configure here.
| } | ||
| .flowOn(dispatchers.io()) | ||
| .onEach { recent -> _viewState.update { it.copy(recentChats = recent) } } | ||
| .launchIn(viewModelScope) |
There was a problem hiding this comment.
Stale chat id after tab switch
High Severity
Opening the contextual sheet on a tab with no stored chat URL updates tabId and SheetMode.INPUT but leaves _chatId and lastSeenChatId from the previous tab’s session. The new recent-chats flow then hides that id from the menu, and observeCurrentChatDeletion can call handleLoadedChatDeleted when the user sends a prompt (WEBVIEW) if that stale chat no longer exists in history—resetting the sheet mid-flow.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit d778585. Configure here.
There was a problem hiding this comment.
I’ve tested and I don’t think this should actually happen. There is no case where the contextual sheet can be opened from a tab with no url but has previously been used.
There was a problem hiding this comment.
This is arguably not a real defect at all under the current architecture.
The report's entire severity case rests on one mechanism: state from "the previous tab's session" bleeding into a new tab. That requires a ViewModel shared across tabs. There isn't one — each tab gets its own DuckChatContextualFragment with a fixed tabId and its own FragmentScope ViewModel, and onSheetOpened runs once per fragment. So:
"leaves _chatId/lastSeenChatId from the previous tab" — can't happen; a new tab's VM starts with both null.
"recent-chats flow hides that id" — only hides whatever this VM's _chatId is, which is null on a fresh INPUT sheet. Nothing wrongly hidden.
"observeCurrentChatDeletion resets mid-flow when you send a prompt" — needs a stale non-null _chatId at prompt time. Within one tab, _chatId is coupled to the persisted URL (set/cleared together), so when the
no-stored-URL branch runs _chatId is already null, and the deletion observer's currentChatId != null guard short-circuits.
YoussefKeyrouz
left a comment
There was a problem hiding this comment.
Works well. Tested different scenarios. Thanks for fixing the issue with burning the chat.
If you can just take a look at the bugbot comment as it was marked as high.



Task/Issue URL: https://app.asana.com/1/137249556945/project/1208671677432066/task/1215444384395010?focus=true
Tech Design URL (if applicable):
Description
See https://app.asana.com/1/137249556945/project/1208671677432066/task/1215444384395010?focus=true
Steps to test this PR
contextualSheetImprovements OFF
contextualSheetImprovements ON, user with NO recent chats
contextualSheetImprovements ON, user with recent chats
UI changes
Before:
https://github.com/user-attachments/assets/3d54c3b2-8c4b-4027-8ca2-c632ef83360b
After:
https://github.com/user-attachments/assets/357b595c-60ce-4812-827a-5cb8acb64251
https://github.com/user-attachments/assets/95a5bed9-de65-4654-9270-8903b1cbb7a7
https://github.com/user-attachments/assets/3ee83bab-b340-4f42-8f5c-760ebc4df279
Note
Medium Risk
Changes contextual sheet UX and tab/navigation flows behind a flag, with non-trivial chat-deletion sync logic; mitigated by broad unit tests and unchanged behavior when the flag is off.
Overview
With
contextualSheetImprovements, the contextual Duck.ai sheet swaps the legacy new-chat control for a chats icon (visible in input mode too) and wires it toChatHistoryRepository.Tapping chats keeps legacy behavior when the flag is off (still starts a new chat). When the flag is on, no recent history opens full chat history; with recents shows a new
popup_contextual_chats_menu(optional New Chat in WEBVIEW, up to five other chats excluding the current one, View All). Selections open a chat in a new browser tab or launch chat history, and the sheet closes first.The ViewModel adds
observeRecentChats, popup/open/history commands, andobserveCurrentChatDeletionso if the loaded chat disappears from history after it was seen, the sheet resets to input without changing bottom-sheet visibility (renderNewChatState(sheetState = null)).DuckChatContextualViewModelTestcovers menu flows, caps/sorting, and deletion edge cases.Reviewed by Cursor Bugbot for commit d778585. Bugbot is set up for automated code reviews on this repo. Configure here.