-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
feat: desktop Search UI revamp #7895
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Reviewer's GuideThis PR overhauls the desktop Search UI by redesigning key components (SearchResultCell, SearchSummaryCell, SearchField, etc.) using AppFlowyThemeData for a consistent look and richer information display, including highlighted text, ancestor paths, and detailed previews. It introduces an "Ask AI" feature through the new SearchAskAiEntrance widget and updates to CommandPaletteBloc, enabling users to query AI, view summaries, and transition to a pre-filled AI chat. The command palette's toggling mechanism and state management were also enhanced to accept more contextual information. Sequence Diagram: "Ask AI" - User Initiates Query to AI ChatsequenceDiagram
actor User
participant CPM as CommandPaletteModal
participant CPB as CommandPaletteBloc
participant SAAE as SearchAskAiEntrance
participant AICP as AI Chat Page (DesktopPromptInput)
User->>CPM: Opens Command Palette & types query "Q"
CPM->>CPB: Event.searchChanged("Q")
CPB-->>SAAE: State updated (query="Q")
SAAE-->>User: Shows "Ask AI for 'Q'"
User->>SAAE: Clicks "Ask AI for 'Q'"
SAAE->>CPB: Event.gointToAskAI(sources=null)
CPB-->>CPB: Updates state (askAI=true)
CPB-->>CPM: Signals to close
CPM-->>User: Closes
Note right of User: Navigates to AI Chat Page
AICP->>AICP: checkForAskingAI() called
AICP-->>CPB: Event.askedAI() (to reset askAI flag)
AICP-->>User: AI Chat pre-filled with "Q"
Sequence Diagram: "Ask AI" - User Asks Follow-up from AI OverviewsequenceDiagram
actor User
participant CPM as CommandPaletteModal
participant CPB as CommandPaletteBloc
participant SAAE as SearchAskAiEntrance
participant SummaryCell as SearchSummaryCell (in _AIOverview)
participant AICP as AI Chat Page (DesktopPromptInput)
User->>CPM: Opens Command Palette & types query "Q"
CPM->>CPB: Event.searchChanged("Q")
CPB-->>CPB: Generates AI summary (summary1 with sources S1)
CPB-->>SAAE: State updated (resultSummaries=[summary1])
SAAE-->>User: Shows AI Overview with summary1
User->>SummaryCell: Clicks "Ask Follow-Up"
SummaryCell->>CPB: Event.gointToAskAI(sources=S1)
CPB-->>CPB: Updates state (askAI=true, askAISources=S1)
CPB-->>CPM: Signals to close
CPM-->>User: Closes
Note right of User: Navigates to AI Chat Page
AICP->>AICP: checkForAskingAI() called
AICP-->>CPB: Event.askedAI() (to reset askAI flag)
AICP-->>User: AI Chat pre-filled with "Q" and sources S1
Sequence Diagram: Updated Search Result Display with Hover PreviewsequenceDiagram
actor User
participant SF as SearchField
participant CPB as CommandPaletteBloc
participant SRL as SearchResultList
participant SRC as SearchResultCell
participant SCP as SearchCellPreview
User->>SF: Types query "project plan"
SF->>CPB: CommandPaletteEvent.searchChanged("project plan")
CPB->>CPB: Performs search, updates state with results
CPB-->>SRL: State updated (resultItems=[item1, item2])
SRL-->>User: Displays list of SearchResultCells
User->>SRC: Hovers over item1 (SearchResultCell)
SRC->>SRL: Notifies SearchResultListBloc (onHoverResult item1)
SRL-->>SRL: Updates its state (hoveredResult=item1)
SRL-->>SCP: Shows SearchResultPreview for item1
SCP-->>User: Displays detailed preview of item1 (title, path, dates, etc.)
Class Diagram: Updated SearchSummaryCell and new _TextInfoclassDiagram
class SearchSummaryCell {
+SearchSummaryPB summary
+double maxWidth
+AppFlowyThemeData theme
+State~SearchSummaryCell~ createState()
+initState() void
+didUpdateWidget(SearchSummaryCell oldWidget) void
+dispose() void
+build(BuildContext context) Widget
+buildReferenceIcon() Widget
+showPopover() void
+hidePopover() void
+refreshTextPainter() void
}
class _SearchSummaryCellState {
-TextPainter _painter
-_TextInfo _textInfo
-bool tappedShowMore
-int maxLines
-PopoverController popoverController
+SearchSummaryPB summary
+double maxWidth
+AppFlowyThemeData theme
}
SearchSummaryCell --|> StatefulWidget
SearchSummaryCell "1" *-- "1" _SearchSummaryCellState : creates
_SearchSummaryCellState "1" *-- "1" _TextInfo : uses
class _TextInfo {
+String text
+bool isOverflow
+_TextInfo(String text, bool isOverflow)
+_TextInfo.normal(String text)
+_TextInfo.overflow(String text)
+build(...) Widget
-_buildHighLightSpan(...) TextSpan
}
note for SearchSummaryCell "Handles display of search summaries, including text truncation, highlighting, and a popover for sources. Changed to StatefulWidget."
Class Diagram: Redesigned SearchResultCellclassDiagram
class SearchResultCell {
+SearchResultItem item
+String? query
+bool isHovered
+State~SearchResultCell~ createState()
}
class _SearchResultCellState {
-FocusNode focusNode
+String viewId
+SearchResultItem item
+dispose() void
-_handleSelection() void
+build(BuildContext context) Widget
+buildIcon(AppFlowyThemeData theme) Widget
+buildPath(AppFlowyThemeData theme) Widget
+buildHighLightSpan(String content, TextStyle normal, TextStyle highlight) TextSpan
+buildSummary(AppFlowyThemeData theme) List~Widget~
}
SearchResultCell --|> StatefulWidget
SearchResultCell "1" *-- "1" _SearchResultCellState : creates
_SearchResultCellState ..> SearchResultListBloc : reads
_SearchResultCellState ..> ViewAncestorBloc : uses
note for SearchResultCell "Redesigned to display individual search results with richer information like title, ancestor path, summary, and highlighting."
Class Diagram: New SearchAskAiEntrance and its StatesclassDiagram
class SearchAskAiEntrance {
+build(BuildContext context) Widget
}
SearchAskAiEntrance --|> StatelessWidget
SearchAskAiEntrance ..> CommandPaletteBloc : reads state
SearchAskAiEntrance ..> _AskAIFor : instantiates / shows
SearchAskAiEntrance ..> _AISearching : instantiates / shows
SearchAskAiEntrance ..> _AIOverview : instantiates / shows
class _AskAIFor {
+build(BuildContext context) Widget
+buildText(BuildContext context) Widget
}
_AskAIFor --|> StatelessWidget
_AskAIFor ..> CommandPaletteBloc : reads state & dispatches event
class _AISearching {
+build(BuildContext context) Widget
}
_AISearching --|> StatelessWidget
class _AIOverview {
+build(BuildContext context) Widget
+buildHeader(BuildContext context) Widget
}
_AIOverview --|> StatelessWidget
_AIOverview ..> CommandPaletteBloc : reads state & dispatches event
_AIOverview ..> SearchSummaryCell : uses
note for SearchAskAiEntrance "New widget for the 'Ask AI' feature, managing different UI states: initial prompt, searching, and displaying AI overview."
Class Diagram: DesktopPromptInput AI Integration UpdateclassDiagram
class DesktopPromptInput {
+void Function(String, PromptFormat?, Map<String, String>) onSubmitted
+void Function(List<String>) onUpdateSelectedSources
+checkForAskingAI() void
<<Widget>>
}
DesktopPromptInput ..> CommandPaletteBloc : reads state & dispatches event
DesktopPromptInput ..> AIPromptInputBloc : reads state & dispatches event
note for DesktopPromptInput "Handles prompt input for AI. Added checkForAskingAI method to integrate with command palette's 'Ask AI' flow, pre-filling query and sources."
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @asjqkkkk - I've reviewed your changes - here's some feedback:
- Consider breaking down
SearchSummaryCell
andSearchResultCell
further, as their responsibilities have significantly increased with the new UI and features. - The 'Ask AI' initiation in
DesktopPromptInput
usingaddPostFrameCallback
might be more robust if triggered directly by a dedicated event fromCommandPaletteBloc
.
Here's what I looked at during the review
- 🟡 General issues: 2 issues found
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟢 Complexity: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
void toggle({ | ||
UserWorkspaceBloc? workspaceBloc, | ||
SpaceBloc? spaceBloc, | ||
}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Expand toggle API with additional dependencies.
Add internal docs clarifying workspaceBloc and spaceBloc expectations for future callers.
void toggle({ | |
UserWorkspaceBloc? workspaceBloc, | |
SpaceBloc? spaceBloc, | |
}) { | |
/// Toggles the command palette's open/close state. | |
/// | |
/// The [workspaceBloc] dependency is expected to handle workspace-related actions | |
/// and state updates, while the [spaceBloc] dependency should manage space-related features. | |
/// | |
/// Providing these dependencies allows consumers to extend the toggle functionality with | |
/// domain-specific behavior when necessary. | |
void toggle({ | |
UserWorkspaceBloc? workspaceBloc, | |
SpaceBloc? spaceBloc, | |
}) { |
frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart
Outdated
Show resolved
Hide resolved
🥷 Ninja i18n – 🛎️ Translations need to be updatedProject
|
lint rule | new reports | level | link |
---|---|---|---|
Missing translation | 203 | warning | contribute (via Fink 🐦) |
frontend/appflowy_flutter/lib/ai/widgets/prompt_input/desktop_prompt_input.dart
Outdated
Show resolved
Hide resolved
frontend/appflowy_flutter/lib/workspace/presentation/command_palette/command_palette.dart
Outdated
Show resolved
Hide resolved
ed60efe
to
76740b2
Compare
76740b2
to
689a9b3
Compare
4129f43
to
a34d7ec
Compare
Feature Preview
PR Checklist
Summary by Sourcery
Revamp the desktop search UI to improve the user experience and add new features for searching and interacting with AI
New Features:
Enhancements:
Chores: