Skip to content
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

chore: improve local ai settings page #7643

Merged

Conversation

richardshiue
Copy link
Collaborator

@richardshiue richardshiue commented Mar 28, 2025

Feature Preview


PR Checklist

  • My code adheres to AppFlowy's Conventions
  • I've listed at least one issue that this PR fixes in the description above.
  • I've added a test(s) to validate changes in this PR, or this PR only contains semantic changes.
  • All existing tests are passing.

Summary by Sourcery

Improve the local AI settings page by refactoring the UI components, state management, and user interaction for the local AI settings

Enhancements:

  • Refactored LocalAIToggleBloc to simplify state management
  • Improved UI components with more consistent styling and layout
  • Enhanced user interaction for local AI settings

Chores:

  • Renamed some files and classes for better clarity
  • Simplified error handling and state management

Copy link

sourcery-ai bot commented Mar 28, 2025

Reviewer's Guide by Sourcery

This pull request improves the local AI settings page by refactoring the UI components, state management, and user interaction for the local AI settings. It includes enhancements to the UI, simplified state management, and better error handling.

Sequence diagram for toggling Local AI setting

Loading
sequenceDiagram
    participant User
    participant LocalAISettingHeader
    participant LocalAIToggleBloc
    participant AIEventToggleLocalAI
    participant LocalAISetting

    User->LocalAISettingHeader: Clicks toggle
    LocalAISettingHeader->LocalAIToggleBloc: add(LocalAIToggleEvent.toggle())
    LocalAIToggleBloc->AIEventToggleLocalAI: send()
    activate AIEventToggleLocalAI
    AIEventToggleLocalAI-->>LocalAIToggleBloc: FlowyResult<LocalAIPB, FlowyError>
    deactivate AIEventToggleLocalAI
    LocalAIToggleBloc->LocalAISetting: add(LocalAIToggleEvent.handleResult(result))

Updated class diagram for LocalAIToggleBloc

Loading
classDiagram
  class LocalAIToggleBloc {
    -AIEventGetLocalAIState getLocalAiState
    -AIEventToggleLocalAI toggleLocalAI
    +LocalAIToggleBloc()
    +Future<void> _handleEvent(LocalAIToggleEvent event, Emitter<LocalAiToggleState> emit)
    +void _handleResult(Emitter<LocalAiToggleState> emit, FlowyResult<LocalAIPB, FlowyError> result)
    +void _getLocalAiState()
  }
  LocalAIToggleBloc --|> Bloc

  LocalAiToggleState <|-- ReadyLocalAiToggleState : extends
  LocalAiToggleState <|-- LoadingLocalAiToggleState : extends
  LocalAiToggleState <|-- ErrorLocalAiToggleState : extends

  class LocalAiToggleState {
    <<sealed>>
  }

  class ReadyLocalAiToggleState {
    -bool isEnabled
    +ReadyLocalAiToggleState(bool isEnabled)
  }

  class LoadingLocalAiToggleState {
    +LoadingLocalAiToggleState()
  }

  class ErrorLocalAiToggleState {
    -FlowyError error
    +ErrorLocalAiToggleState(FlowyError error)
  }

  LocalAIToggleEvent <|-- _Toggle : extends
  LocalAIToggleEvent <|-- _HandleResult : extends

  class LocalAIToggleEvent {
    <<sealed>>
  }

  class _Toggle {
    +_Toggle()
  }

  class _HandleResult {
    -FlowyResult<LocalAIPB, FlowyError> result
    +_HandleResult(FlowyResult<LocalAIPB, FlowyError> result)
  }

  note for LocalAIToggleBloc "Refactored to simplify state management and improve error handling"

File-Level Changes

Change Details Files
Refactored the LocalAISetting widget to use StatefulWidget and BlocConsumer for better state management and UI updates.
  • Converted LocalAISetting to a StatefulWidget.
  • Used BlocConsumer to listen to state changes in LocalAIToggleBloc and update the UI accordingly.
  • Initialized ExpandableController to manage the expanded state of the expandable panel.
  • Disposed of ExpandableController in the dispose method to prevent memory leaks.
  • Updated the ExpandablePanel to use the expandableController for managing its expanded state.
  • Modified the LocalAiSettingHeader to receive isEnabled and isToggleable properties for dynamic UI updates.
frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/local_ai_setting.dart
Improved the LocalAiSettingHeader widget to handle toggle changes and confirmation dialogs more efficiently.
  • Added isEnabled and isToggleable properties to LocalAiSettingHeader to control the state of the toggle.
  • Wrapped the Toggle widget with IgnorePointer and Opacity to disable and visually indicate when the toggle is not interactable.
  • Implemented the _onToggleChanged method to handle toggle changes and display a confirmation dialog when disabling the local AI.
  • Removed the BlocBuilder from the header and moved the logic to the parent widget.
frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/local_ai_setting.dart
Enhanced the PluginStateIndicator widget to provide better visual feedback and user experience.
  • Added a SizedBox to constrain the height of the PluginStateIndicator.
  • Updated the _RestartPluginButton widget to use a DecoratedBox for better visual styling.
  • Improved the styling of the _LocalAIRunning widget with a DecoratedBox and updated padding.
  • Replaced FlowySvgs.download_warn_s with FlowySvgs.toast_warning_filled_s in _RestartPluginButton.
  • Replaced FlowySvgs.toast_warning_filled_s with FlowySvgs.toast_error_filled_s in _LackOfResource.
frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/plugin_state.dart
Refactored LocalAIToggleBloc to simplify state management and event handling.
  • Modified LocalAIToggleBloc to extend Bloc<LocalAIToggleEvent, LocalAiToggleState>.
  • Replaced LocalAIToggleState with a sealed class LocalAiToggleState and its subclasses: ReadyLocalAiToggleState, LoadingLocalAiToggleState, and ErrorLocalAiToggleState.
  • Removed the LocalAIToggleStateIndicator and integrated its functionality directly into the LocalAiToggleState sealed class.
  • Updated the _handleEvent method to use the new state management approach.
  • Added _getLocalAiState to fetch the local AI state when the bloc is initialized.
  • Removed the started event.
frontend/appflowy_flutter/lib/workspace/application/settings/ai/local_ai_bloc.dart
Improved the UI of InitLocalAIIndicator with better styling and visual feedback.
  • Updated the styling of the InitLocalAIIndicator with a DecoratedBox and updated padding.
  • Consolidated the UI logic for different running states within the InitLocalAIIndicator.
  • Removed the SizedBox widget and directly returned the FlowyText widget for Connecting and Connected states.
  • Removed the height constraint from the Running state.
frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/init_local_ai.dart
Introduced a new OllamaSettingPage widget to manage Ollama settings.
  • Created a new OllamaSettingPage widget with UI components for managing Ollama settings.
  • Implemented a _SettingItemWidget to display individual setting items with labels and text fields.
  • Added a _SaveButton to apply the changes made to the settings.
  • Included an _InstallOllamaInstruction widget to provide instructions on how to install Ollama.
  • Used ListView.separated to display the setting items with separators.
  • Utilized FlowyTextField for editable setting values.
frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/ollama_setting.dart
Renamed ollma_setting.dart to ollama_setting.dart.
  • Renamed the file to follow naming conventions.
frontend/appflowy_flutter/lib/workspace/presentation/settings/pages/setting_ai_view/ollma_setting.dart
Updated the description of PendingResource::PluginExecutableNotReady in resource.rs.
  • Removed the extra information from the description.
frontend/rust-lib/flowy-ai/src/local_ai/resource.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@richardshiue richardshiue marked this pull request as ready for review March 28, 2025 03:32
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey @richardshiue - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider extracting the toggle logic into a separate widget or function for better readability and maintainability.
  • The PluginStateIndicator and InitLocalAIIndicator widgets could benefit from more descriptive names to better reflect their purpose.
Here's what I looked at during the review
  • 🟡 General issues: 1 issue found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟢 Complexity: all looks good
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

}
}

class _SettingItemWidget extends StatelessWidget {
Copy link

Choose a reason for hiding this comment

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

suggestion (bug_risk): Key generation for setting items may need caution.

Using ValueKey(item.content + item.settingType.title) is concise, but ensure that the concatenated string always produces a unique key, especially if item content or title might revert to similar values. Consider whether a more robust unique identifier might be beneficial.

Suggested implementation:

class _SettingItemWidget extends StatelessWidget {
  const _SettingItemWidget({Key? key, required this.item}) : super(key: key);

 // Wherever _SettingItemWidget is created, update key generation.
 // For example:
 // key: ValueKey(item.id)

Make sure in all the widget instantiations where you currently build the _SettingItemWidget with a key like ValueKey(item.content + item.settingType.title), update it to use ValueKey(item.id) (or another reliably unique identifier from your data). If your item model does not have an "id", consider adding one or using another unique property.

@richardshiue richardshiue force-pushed the chore/improve-local-ai-setting-page branch from 65865ee to 36ab09f Compare March 28, 2025 05:26
@richardshiue richardshiue force-pushed the chore/improve-local-ai-setting-page branch from e4c5935 to 4f81b88 Compare March 29, 2025 06:49
Copy link

github-actions bot commented Mar 29, 2025

🥷 Ninja i18n – 🛎️ Translations need to be updated

Project /project.inlang

lint rule new reports level link
Message without source 1 warning contribute (via Fink 🐦)
Missing translation 87 warning contribute (via Fink 🐦)

@richardshiue richardshiue force-pushed the chore/improve-local-ai-setting-page branch from 4f81b88 to dfccffa Compare March 29, 2025 06:59
@richardshiue richardshiue force-pushed the chore/improve-local-ai-setting-page branch from dfccffa to 12a93a5 Compare March 29, 2025 07:00
@richardshiue richardshiue merged commit 3a879b0 into AppFlowy-IO:main Mar 29, 2025
17 of 18 checks passed
@richardshiue richardshiue deleted the chore/improve-local-ai-setting-page branch March 29, 2025 13:56
appflowy added a commit that referenced this pull request Mar 30, 2025
@richardshiue richardshiue restored the chore/improve-local-ai-setting-page branch March 30, 2025 06:29
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