From d5cfd054cc8a7dad5c84aeec314d0bacc6a86a8a Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Mon, 3 Jun 2024 23:20:33 +0800 Subject: [PATCH 01/11] chore: add default questions (#5457) * chore: add default questions * chore: fix mobile ui * chore: send button * chore: send button --- .../bottom_sheet_add_new_page.dart | 9 ++ .../default_mobile_action_pane.dart | 4 +- .../home/shared/mobile_view_card.dart | 10 +-- .../page_item/mobile_view_item.dart | 3 +- .../lib/plugins/ai_chat/chat_page.dart | 79 +++++++++++------- .../ai_chat/presentation/chat_input.dart | 31 ++++++- .../presentation/chat_related_question.dart | 5 +- .../presentation/chat_welcome_page.dart | 82 ++++++++++++++++++- .../lib/style_widget/icon_button.dart | 1 + frontend/resources/translations/en.json | 6 +- 10 files changed, 187 insertions(+), 43 deletions(-) diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart index 18c5c3a6df..9bd6f22880 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart @@ -55,6 +55,15 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { showTopBorder: false, onTap: () => onAction(ViewLayoutPB.Calendar), ), + FlowyOptionTile.text( + text: LocaleKeys.chat_newChat.tr(), + leftIcon: const FlowySvg( + FlowySvgs.chat_ai_page_s, + size: Size.square(18), + ), + showTopBorder: false, + onTap: () => onAction(ViewLayoutPB.Chat), + ), ], ); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart index 327db627c4..17ca604717 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart @@ -3,6 +3,7 @@ import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; import 'package:appflowy/mobile/presentation/page_item/mobile_slide_action_button.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/view/view_bloc.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -76,7 +77,8 @@ enum MobilePaneActionType { .addToFavorites, MobileViewItemBottomSheetBodyAction.divider, MobileViewItemBottomSheetBodyAction.rename, - MobileViewItemBottomSheetBodyAction.duplicate, + if (state.view.layout != ViewLayoutPB.Chat) + MobileViewItemBottomSheetBodyAction.duplicate, MobileViewItemBottomSheetBodyAction.divider, MobileViewItemBottomSheetBodyAction.delete, ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart index c4498a27cd..78f03569be 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart @@ -257,10 +257,9 @@ class MobileViewCard extends StatelessWidget { ], child: BlocBuilder( builder: (context, state) { - final isFavorite = state.view.isFavorite; return MobileViewItemBottomSheet( view: viewBloc.state.view, - actions: _buildActions(isFavorite), + actions: _buildActions(state.view), ); }, ), @@ -269,15 +268,16 @@ class MobileViewCard extends StatelessWidget { ); } - List _buildActions(bool isFavorite) { + List _buildActions(ViewPB view) { switch (type) { case MobileViewCardType.recent: return [ - isFavorite + view.isFavorite ? MobileViewItemBottomSheetBodyAction.removeFromFavorites : MobileViewItemBottomSheetBodyAction.addToFavorites, MobileViewItemBottomSheetBodyAction.divider, - MobileViewItemBottomSheetBodyAction.duplicate, + if (view.layout != ViewLayoutPB.Chat) + MobileViewItemBottomSheetBodyAction.duplicate, MobileViewItemBottomSheetBodyAction.divider, MobileViewItemBottomSheetBodyAction.removeFromRecent, ]; diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart index e21ff3be20..4b4672f6a7 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart @@ -413,7 +413,8 @@ class _SingleMobileInnerViewItemState extends State { MobileViewItemBottomSheetBodyAction.divider, MobileViewItemBottomSheetBodyAction.rename, MobileViewItemBottomSheetBodyAction.divider, - MobileViewItemBottomSheetBodyAction.duplicate, + if (state.view.layout != ViewLayoutPB.Chat) + MobileViewItemBottomSheetBodyAction.duplicate, MobileViewItemBottomSheetBodyAction.divider, MobileViewItemBottomSheetBodyAction.delete, ], diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/chat_page.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/chat_page.dart index 4d103e342f..3e6142c3ec 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/chat_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/chat_page.dart @@ -25,6 +25,29 @@ import 'presentation/chat_theme.dart'; import 'presentation/chat_user_invalid_message.dart'; import 'presentation/chat_welcome_page.dart'; +class AIChatUILayout { + static EdgeInsets get chatPadding => + isMobile ? EdgeInsets.zero : const EdgeInsets.symmetric(horizontal: 70); + + static EdgeInsets get welcomePagePadding => isMobile + ? const EdgeInsets.symmetric(horizontal: 20) + : const EdgeInsets.symmetric(horizontal: 100); + + static double get messageWidthRatio => 0.85; + + static EdgeInsets safeAreaInsets(BuildContext context) { + final query = MediaQuery.of(context); + return isMobile + ? EdgeInsets.fromLTRB( + query.padding.left, + 0, + query.padding.right, + query.viewInsets.bottom + query.padding.bottom, + ) + : const EdgeInsets.symmetric(horizontal: 70); + } +} + class AIChatPage extends StatefulWidget { const AIChatPage({ super.key, @@ -67,7 +90,7 @@ class _AIChatPageState extends State { Widget buildChatWidget() { return SizedBox.expand( child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 60), + padding: AIChatUILayout.chatPadding, child: BlocProvider( create: (context) => ChatBloc( view: widget.view, @@ -99,13 +122,22 @@ class _AIChatPageState extends State { builder: (context, state) { return state.initialLoadingStatus == const LoadingState.finish() - ? const ChatWelcomePage() + ? Padding( + padding: AIChatUILayout.welcomePagePadding, + child: ChatWelcomePage( + onSelectedQuestion: (question) { + blocContext + .read() + .add(ChatEvent.sendMessage(question)); + }, + ), + ) : const Center( child: CircularProgressIndicator.adaptive(), ); }, ), - messageWidthRatio: isMobile ? 0.8 : 0.86, + messageWidthRatio: AIChatUILayout.messageWidthRatio, bubbleBuilder: ( child, { required message, @@ -248,35 +280,26 @@ class _AIChatPageState extends State { } Widget buildChatInput(BuildContext context) { - final query = MediaQuery.of(context); - final safeAreaInsets = isMobile - ? EdgeInsets.fromLTRB( - query.padding.left, - 0, - query.padding.right, - query.viewInsets.bottom + query.padding.bottom, - ) - : const EdgeInsets.symmetric(horizontal: 70); - return Column( - children: [ - ClipRect( - child: Padding( - padding: safeAreaInsets, - child: ChatInput( + return ClipRect( + child: Padding( + padding: AIChatUILayout.safeAreaInsets(context), + child: Column( + children: [ + ChatInput( chatId: widget.view.id, onSendPressed: (message) => onSendPressed(context, message.text), ), - ), + const VSpace(6), + Opacity( + opacity: 0.6, + child: FlowyText( + LocaleKeys.chat_aiMistakePrompt.tr(), + fontSize: 12, + ), + ), + ], ), - const VSpace(6), - Opacity( - opacity: 0.6, - child: FlowyText( - LocaleKeys.chat_aiMistakePrompt.tr(), - fontSize: 12, - ), - ), - ], + ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart index 732726b952..a981ab9b33 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart @@ -1,6 +1,8 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme_extension.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -109,7 +111,7 @@ class _ChatInputState extends State { child: Padding( padding: inputPadding, child: Material( - borderRadius: BorderRadius.circular(12), + borderRadius: BorderRadius.circular(30), color: isMobile ? Theme.of(context).colorScheme.surfaceContainer : Theme.of(context).colorScheme.surfaceContainerHighest, @@ -169,9 +171,11 @@ class _ChatInputState extends State { ), child: Visibility( visible: _sendButtonVisible, - child: SendButton( - onPressed: _handleSendPressed, + child: Padding( padding: buttonPadding, + child: SendButton( + onPressed: _handleSendPressed, + ), ), ), ); @@ -255,3 +259,24 @@ class InputOptions { final isMobile = defaultTargetPlatform == TargetPlatform.android || defaultTargetPlatform == TargetPlatform.iOS; + +class SendButton extends StatelessWidget { + const SendButton({required this.onPressed, super.key}); + + final void Function() onPressed; + + @override + Widget build(BuildContext context) { + return FlowyIconButton( + width: 36, + fillColor: Theme.of(context).colorScheme.secondary, + radius: BorderRadius.circular(18), + icon: FlowySvg( + FlowySvgs.send_s, + size: const Size.square(24), + color: Theme.of(context).colorScheme.primary, + ), + onPressed: onPressed, + ); + } +} diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart index f4709f2263..0cf2398f68 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_related_question.dart @@ -71,9 +71,10 @@ class RelatedQuestionList extends StatelessWidget { padding: const EdgeInsets.all(12), child: Row( children: [ - const FlowySvg( + FlowySvg( FlowySvgs.ai_summary_generate_s, - size: Size.square(24), + size: const Size.square(24), + color: Theme.of(context).colorScheme.primary, ), const HSpace(6), FlowyText( diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_welcome_page.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_welcome_page.dart index e6fc55a15a..1014b9ef5e 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_welcome_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_welcome_page.dart @@ -1,10 +1,88 @@ +import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; +import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flutter/material.dart'; +import 'chat_input.dart'; + class ChatWelcomePage extends StatelessWidget { - const ChatWelcomePage({super.key}); + ChatWelcomePage({required this.onSelectedQuestion, super.key}); + + final void Function(String) onSelectedQuestion; + + final List items = [ + LocaleKeys.chat_question1.tr(), + LocaleKeys.chat_question2.tr(), + LocaleKeys.chat_question3.tr(), + LocaleKeys.chat_question4.tr(), + ]; + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const FlowySvg( + FlowySvgs.flowy_ai_chat_logo_s, + size: Size.square(44), + ), + const SizedBox(height: 40), + GridView.builder( + shrinkWrap: true, + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: isMobile ? 2 : 4, + crossAxisSpacing: 6, + mainAxisSpacing: 6, + childAspectRatio: 16.0 / 9.0, + ), + itemCount: items.length, + itemBuilder: (context, index) => WelcomeQuestion( + question: items[index], + onSelected: onSelectedQuestion, + ), + ), + ], + ); + } +} + +class WelcomeQuestion extends StatelessWidget { + const WelcomeQuestion({ + required this.question, + required this.onSelected, + super.key, + }); + + final void Function(String) onSelected; + final String question; @override Widget build(BuildContext context) { - return const SizedBox.shrink(); + return InkWell( + onTap: () => onSelected(question), + child: GestureDetector( + behavior: HitTestBehavior.opaque, + child: FlowyHover( + // Make the hover effect only available on mobile + isSelected: () => isMobile, + style: HoverStyle( + borderRadius: BorderRadius.circular(6), + ), + child: Padding( + padding: const EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + FlowyText( + question, + maxLines: null, + ), + ], + ), + ), + ), + ), + ); } } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/icon_button.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/icon_button.dart index 116158b10b..b4a2553814 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/icon_button.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/icon_button.dart @@ -84,6 +84,7 @@ class FlowyIconButton extends StatelessWidget { richMessage: richTooltipText, showDuration: Duration.zero, child: RawMaterialButton( + clipBehavior: Clip.antiAlias, visualDensity: VisualDensity.compact, hoverElevation: 0, highlightElevation: 0, diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index a56b6ff9b3..38057a15b0 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -153,9 +153,13 @@ "unsupportedCloudPrompt": "This feature is only available when using AppFlowy Cloud", "relatedQuestion": "Related", "serverUnavailable": "Service Temporarily Unavailable. Please try again later.", - "aiServerUnavailable": "There was an error generating a response.", + "aiServerUnavailable": "🌈 Uh-oh! 🌈. A unicorn ate our response. Please retry!", "clickToRetry": "Click to retry", "regenerateAnswer": "Regenerate", + "question1": "How to use Kanban to manage tasks", + "question2": "Explain the GTD method", + "question3": "Why use Rust", + "question4": "Recipe with what's in my kitchen", "aiMistakePrompt": "AI can make mistakes. Check important info." }, "trash": { From 03e8dba5f349f8237db52ad65c94b1b1d7c5879f Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 4 Jun 2024 09:22:47 +0800 Subject: [PATCH 02/11] fix: improve sidebar UI (#5453) * fix: revert dark main color * fix: workspace name font size * fix: only show collapse button when hovering the sidebar * fix: remove expand button after workspace name * fix: change settings icon opactiy to 0.7 * chore: replace favorite icon * chore: add arrow icon after section name * chore: replace trash bin icon * chore: adjust collapse icon padding * feat: redesign question bubble * fix: replace favorite icon * fix: remove trash button padding * chore: replace hover color * feat: add more padding to tooltip * feat: add hover effect to arrow icon * feat: add hover effect to add view button * fix: view title color * feat: replace question bubble * feat: replace default page icon * fix: header icon size * fix: add view button padding * fix: unable to insert default image on desktop * fix: notification button size issue * fix: workspace icon size * feat: add a divider between favorite space and add new page button --- .../lib/core/frameless_window.dart | 2 +- .../lib/plugins/database/board/board.dart | 2 +- .../plugins/database/calendar/calendar.dart | 4 +- .../lib/plugins/database/grid/grid.dart | 4 +- .../database_document_plugin.dart | 2 +- .../lib/plugins/document/document.dart | 4 +- .../editor_plugins/header/cover_editor.dart | 11 +- .../editor_plugins/header/desktop_cover.dart | 2 +- .../header/document_header_node_widget.dart | 4 +- .../migration/editor_migration.dart | 8 +- .../workspace/application/view/view_ext.dart | 8 +- .../sidebar/favorites/favorite_folder.dart | 23 ++- .../menu/sidebar/folder/_folder_header.dart | 53 +++++-- .../menu/sidebar/folder/_section_folder.dart | 1 + .../menu/sidebar/footer/sidebar_footer.dart | 31 ++-- .../menu/sidebar/header/sidebar_top_menu.dart | 34 +++-- .../menu/sidebar/shared/sidebar_folder.dart | 16 +- .../shared/sidebar_new_page_button.dart | 16 +- .../menu/sidebar/shared/sidebar_setting.dart | 8 +- .../home/menu/sidebar/sidebar.dart | 137 ++++++++++-------- .../workspace/_sidebar_workspace_icon.dart | 16 +- .../sidebar/workspace/sidebar_workspace.dart | 22 ++- .../home/menu/view/view_add_button.dart | 8 +- .../home/menu/view/view_item.dart | 32 ++-- .../presentation/home/navigation.dart | 13 +- .../widgets/notification_button.dart | 11 +- .../presentation/widgets/favorite_button.dart | 3 +- .../widgets/float_bubble/question_bubble.dart | 66 ++++++--- .../presentation/widgets/pop_up_action.dart | 3 +- .../presentation/widgets/view_title_bar.dart | 33 +++-- .../lib/colorscheme/default_colorscheme.dart | 6 +- .../flowy_infra_ui/lib/style_widget/text.dart | 1 - .../lib/widget/flowy_tooltip.dart | 1 + .../packages/flowy_svg/lib/src/flowy_svg.dart | 10 +- .../resources/flowy_icons/16x/favorited.svg | 3 + .../resources/flowy_icons/16x/help_center.svg | 11 ++ .../resources/flowy_icons/16x/icon_board.svg | 5 + .../flowy_icons/16x/icon_calendar.svg | 3 + .../flowy_icons/16x/icon_document.svg | 4 + .../resources/flowy_icons/16x/icon_grid.svg | 3 + .../resources/flowy_icons/16x/icon_import.svg | 5 + .../16x/workspace_drop_down_menu_hide.svg | 9 +- .../16x/workspace_drop_down_menu_show.svg | 9 +- .../flowy_icons/24x/favorite_header_icon.svg | 3 + .../resources/flowy_icons/24x/new_app.svg | 5 + .../flowy_icons/24x/sidebar_footer_trash.svg | 9 ++ 46 files changed, 423 insertions(+), 241 deletions(-) create mode 100644 frontend/resources/flowy_icons/16x/favorited.svg create mode 100644 frontend/resources/flowy_icons/16x/help_center.svg create mode 100644 frontend/resources/flowy_icons/16x/icon_board.svg create mode 100644 frontend/resources/flowy_icons/16x/icon_calendar.svg create mode 100644 frontend/resources/flowy_icons/16x/icon_document.svg create mode 100644 frontend/resources/flowy_icons/16x/icon_grid.svg create mode 100644 frontend/resources/flowy_icons/16x/icon_import.svg create mode 100644 frontend/resources/flowy_icons/24x/favorite_header_icon.svg create mode 100644 frontend/resources/flowy_icons/24x/new_app.svg create mode 100644 frontend/resources/flowy_icons/24x/sidebar_footer_trash.svg diff --git a/frontend/appflowy_flutter/lib/core/frameless_window.dart b/frontend/appflowy_flutter/lib/core/frameless_window.dart index fcd955fc93..c322da97aa 100644 --- a/frontend/appflowy_flutter/lib/core/frameless_window.dart +++ b/frontend/appflowy_flutter/lib/core/frameless_window.dart @@ -127,7 +127,7 @@ class MoveWindowDetectorState extends State { onPressed: () => context .read() .add(const HomeSettingEvent.collapseMenu()), - iconPadding: const EdgeInsets.fromLTRB(4, 4, 4, 4), + iconPadding: const EdgeInsets.all(4.0), icon: context.read().state.isMenuCollapsed ? const FlowySvg(FlowySvgs.show_menu_s) : const FlowySvg(FlowySvgs.hide_menu_m), diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/board.dart b/frontend/appflowy_flutter/lib/plugins/database/board/board.dart index 86851c4bbb..f8fb18a561 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/board.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/board.dart @@ -19,7 +19,7 @@ class BoardPluginBuilder implements PluginBuilder { String get menuName => LocaleKeys.board_menuName.tr(); @override - FlowySvgData get icon => FlowySvgs.board_s; + FlowySvgData get icon => FlowySvgs.icon_board_s; @override PluginType get pluginType => PluginType.board; diff --git a/frontend/appflowy_flutter/lib/plugins/database/calendar/calendar.dart b/frontend/appflowy_flutter/lib/plugins/database/calendar/calendar.dart index 861d9f4303..54667d5f69 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/calendar/calendar.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/calendar/calendar.dart @@ -2,8 +2,8 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/tab_bar/tab_bar_view.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; -import 'package:easy_localization/easy_localization.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; class CalendarPluginBuilder extends PluginBuilder { @override @@ -19,7 +19,7 @@ class CalendarPluginBuilder extends PluginBuilder { String get menuName => LocaleKeys.calendar_menuName.tr(); @override - FlowySvgData get icon => FlowySvgs.date_s; + FlowySvgData get icon => FlowySvgs.icon_calendar_s; @override PluginType get pluginType => PluginType.calendar; diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/grid.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/grid.dart index 1f8816d92b..b43c425a9d 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/grid.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/grid.dart @@ -2,8 +2,8 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/tab_bar/tab_bar_view.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; -import 'package:easy_localization/easy_localization.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:easy_localization/easy_localization.dart'; class GridPluginBuilder implements PluginBuilder { @override @@ -19,7 +19,7 @@ class GridPluginBuilder implements PluginBuilder { String get menuName => LocaleKeys.grid_menuName.tr(); @override - FlowySvgData get icon => FlowySvgs.grid_s; + FlowySvgData get icon => FlowySvgs.icon_grid_s; @override PluginType get pluginType => PluginType.grid; diff --git a/frontend/appflowy_flutter/lib/plugins/database_document/database_document_plugin.dart b/frontend/appflowy_flutter/lib/plugins/database_document/database_document_plugin.dart index cd709e2154..e415aaa12e 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_document/database_document_plugin.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_document/database_document_plugin.dart @@ -44,7 +44,7 @@ class DatabaseDocumentPluginBuilder extends PluginBuilder { String get menuName => LocaleKeys.document_menuName.tr(); @override - FlowySvgData get icon => FlowySvgs.document_s; + FlowySvgData get icon => FlowySvgs.icon_document_s; @override PluginType get pluginType => PluginType.databaseDocument; diff --git a/frontend/appflowy_flutter/lib/plugins/document/document.dart b/frontend/appflowy_flutter/lib/plugins/document/document.dart index cb48cd1bba..b13ce1221c 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document.dart @@ -37,7 +37,7 @@ class DocumentPluginBuilder extends PluginBuilder { String get menuName => LocaleKeys.document_menuName.tr(); @override - FlowySvgData get icon => FlowySvgs.document_s; + FlowySvgData get icon => FlowySvgs.icon_document_s; @override PluginType get pluginType => PluginType.document; @@ -148,7 +148,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder ? [ DocumentCollaborators( key: ValueKey('collaborators_${view.id}'), - width: 150, + width: 120, height: 32, view: view, ), diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/cover_editor.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/cover_editor.dart index aac0713a7d..60211b9024 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/cover_editor.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/cover_editor.dart @@ -1,14 +1,17 @@ import 'dart:ui'; -import 'package:flutter/material.dart'; - import 'package:appflowy_editor/appflowy_editor.dart'; +import 'package:flutter/material.dart'; const String kLocalImagesKey = 'local_images'; List get builtInAssetImages => [ - "assets/images/app_flowy_abstract_cover_1.jpg", - "assets/images/app_flowy_abstract_cover_2.jpg", + 'assets/images/built_in_cover_images/m_cover_image_1.jpg', + 'assets/images/built_in_cover_images/m_cover_image_2.jpg', + 'assets/images/built_in_cover_images/m_cover_image_3.jpg', + 'assets/images/built_in_cover_images/m_cover_image_4.jpg', + 'assets/images/built_in_cover_images/m_cover_image_5.jpg', + 'assets/images/built_in_cover_images/m_cover_image_6.jpg', ]; class ColorOption { diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/desktop_cover.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/desktop_cover.dart index 7e576363cd..e8d04d7161 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/desktop_cover.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/desktop_cover.dart @@ -155,7 +155,7 @@ class _DesktopCoverState extends State { ); case CoverType.asset: return Image.asset( - widget.coverDetails!, + PageStyleCoverImageType.builtInImagePath(detail), fit: BoxFit.cover, ); case CoverType.color: diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart index 3a22909744..3ac9067b89 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/header/document_header_node_widget.dart @@ -28,8 +28,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:string_validator/string_validator.dart'; -import 'cover_editor.dart'; - const double kCoverHeight = 250.0; const double kIconHeight = 60.0; const double kToolbarHeight = 40.0; // with padding to the top @@ -296,7 +294,7 @@ class _DocumentHeaderToolbarState extends State { leftIconSize: const Size.square(18), onTap: () => widget.onIconOrCoverChanged( cover: PlatformExtension.isDesktopOrWeb - ? (CoverType.asset, builtInAssetImages.first) + ? (CoverType.asset, '1') : (CoverType.color, '0xffe8e0ff'), ), useIntrinsicWidth: true, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/migration/editor_migration.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/migration/editor_migration.dart index d97e6a5bc6..664e2143b6 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/migration/editor_migration.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/migration/editor_migration.dart @@ -191,7 +191,13 @@ class EditorMigration { } else { switch (coverType) { case CoverType.asset: - // The new version does not support the asset cover. + extra = { + ViewExtKeys.coverKey: { + ViewExtKeys.coverTypeKey: + PageStyleCoverImageType.builtInImage.toString(), + ViewExtKeys.coverValueKey: coverDetails, + }, + }; break; case CoverType.color: extra = { diff --git a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart index 4835c795ba..ca32823d65 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart @@ -41,10 +41,10 @@ class ViewExtKeys { extension ViewExtension on ViewPB { Widget defaultIcon() => FlowySvg( switch (layout) { - ViewLayoutPB.Board => FlowySvgs.board_s, - ViewLayoutPB.Calendar => FlowySvgs.calendar_s, - ViewLayoutPB.Grid => FlowySvgs.grid_s, - ViewLayoutPB.Document => FlowySvgs.document_s, + ViewLayoutPB.Board => FlowySvgs.icon_board_s, + ViewLayoutPB.Calendar => FlowySvgs.icon_calendar_s, + ViewLayoutPB.Grid => FlowySvgs.icon_grid_s, + ViewLayoutPB.Document => FlowySvgs.icon_document_s, ViewLayoutPB.Chat => FlowySvgs.chat_ai_page_s, _ => FlowySvgs.document_s, }, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart index 1e6279f304..a3cb50fd06 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart @@ -134,15 +134,22 @@ class FavoriteHeader extends StatelessWidget { @override Widget build(BuildContext context) { - return FlowyButton( - onTap: onPressed, - margin: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 7.0), - leftIcon: const FlowySvg( - FlowySvgs.favorite_header_icon_s, - blendMode: null, + return SizedBox( + height: HomeSizes.newPageSectionHeight, + child: FlowyButton( + onTap: onPressed, + margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 3.0), + leftIcon: const FlowySvg( + FlowySvgs.favorite_header_icon_m, + blendMode: null, + ), + leftIconSize: const Size.square(24.0), + iconPadding: 8.0, + text: FlowyText.regular( + LocaleKeys.sideBar_favorites.tr(), + lineHeight: 1.15, + ), ), - iconPadding: 10.0, - text: FlowyText.regular(LocaleKeys.sideBar_favorites.tr()), ); } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart index c5042c4de4..d73060d0b3 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_folder_header.dart @@ -1,4 +1,5 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; @@ -11,6 +12,7 @@ class FolderHeader extends StatefulWidget { required this.addButtonTooltip, required this.onPressed, required this.onAdded, + required this.isExpanded, }); final String title; @@ -18,6 +20,7 @@ class FolderHeader extends StatefulWidget { final String addButtonTooltip; final VoidCallback onPressed; final VoidCallback onAdded; + final bool isExpanded; @override State createState() => _FolderHeaderState(); @@ -34,24 +37,42 @@ class _FolderHeaderState extends State { @override Widget build(BuildContext context) { - return MouseRegion( - onEnter: (_) => isHovered.value = true, - onExit: (_) => isHovered.value = false, - child: FlowyButton( - onTap: widget.onPressed, - margin: const EdgeInsets.symmetric(horizontal: 6.0), - rightIcon: ValueListenableBuilder( - valueListenable: isHovered, - builder: (context, onHover, child) => - Opacity(opacity: onHover ? 1 : 0, child: child), - child: FlowyIconButton( - tooltipText: widget.addButtonTooltip, - icon: const FlowySvg(FlowySvgs.view_item_add_s), - onPressed: widget.onAdded, + return SizedBox( + height: HomeSizes.workspaceSectionHeight, + child: MouseRegion( + onEnter: (_) => isHovered.value = true, + onExit: (_) => isHovered.value = false, + child: FlowyButton( + onTap: widget.onPressed, + margin: const EdgeInsets.only(left: 6.0, right: 4.0), + rightIcon: ValueListenableBuilder( + valueListenable: isHovered, + builder: (context, onHover, child) => + Opacity(opacity: onHover ? 1 : 0, child: child), + child: FlowyIconButton( + width: 24, + iconPadding: const EdgeInsets.all(4.0), + tooltipText: widget.addButtonTooltip, + icon: const FlowySvg(FlowySvgs.view_item_add_s), + onPressed: widget.onAdded, + ), + ), + iconPadding: 10.0, + text: Row( + children: [ + FlowyText( + widget.title, + lineHeight: 1.15, + ), + const HSpace(4.0), + FlowySvg( + widget.isExpanded + ? FlowySvgs.workspace_drop_down_menu_show_s + : FlowySvgs.workspace_drop_down_menu_hide_s, + ), + ], ), ), - iconPadding: 10.0, - text: FlowyText(widget.title), ), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart index bd83e06934..c957a664c2 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/folder/_section_folder.dart @@ -76,6 +76,7 @@ class _SectionFolderState extends State { Widget _buildHeader(BuildContext context) { return FolderHeader( title: widget.title, + isExpanded: context.watch().state.isExpanded, expandButtonTooltip: widget.expandButtonTooltip, addButtonTooltip: widget.addButtonTooltip, onPressed: () => diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/footer/sidebar_footer.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/footer/sidebar_footer.dart index 6c16609a33..8af1c0eb9e 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/footer/sidebar_footer.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/footer/sidebar_footer.dart @@ -1,8 +1,12 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; +import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/home/menu/menu_shared_state.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; class SidebarFooter extends StatelessWidget { @@ -31,12 +35,20 @@ class SidebarTrashButton extends StatelessWidget { @override Widget build(BuildContext context) { - return ValueListenableBuilder( - valueListenable: getIt().notifier, - builder: (context, value, child) { - return MouseRegion( - cursor: SystemMouseCursors.click, - child: GestureDetector( + return SizedBox( + height: HomeSizes.workspaceSectionHeight, + child: ValueListenableBuilder( + valueListenable: getIt().notifier, + builder: (context, value, child) { + return FlowyButton( + leftIcon: const FlowySvg(FlowySvgs.sidebar_footer_trash_m), + leftIconSize: const Size.square(24.0), + iconPadding: 8.0, + margin: const EdgeInsets.all(4.0), + text: FlowyText.regular( + LocaleKeys.trash_text.tr(), + lineHeight: 1.15, + ), onTap: () { getIt().latestOpenView = null; getIt().add( @@ -45,10 +57,9 @@ class SidebarTrashButton extends StatelessWidget { ), ); }, - child: const FlowySvg(FlowySvgs.sidebar_footer_trash_s), - ), - ); - }, + ); + }, + ), ); } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart index c7dc54126e..240a660966 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart @@ -23,8 +23,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; class SidebarTopMenu extends StatelessWidget { const SidebarTopMenu({ super.key, + required this.isSidebarOnHover, }); + final ValueNotifier isSidebarOnHover; + @override Widget build(BuildContext context) { return BlocBuilder( @@ -80,17 +83,26 @@ class SidebarTopMenu extends StatelessWidget { ], ); - return Padding( - padding: const EdgeInsets.only(top: 12.0), - child: FlowyTooltip( - richMessage: textSpan, - child: FlowyIconButton( - width: 24, - onPressed: () => context - .read() - .add(const HomeSettingEvent.collapseMenu()), - iconPadding: const EdgeInsets.all(2), - icon: const FlowySvg(FlowySvgs.hide_menu_s), + return ValueListenableBuilder( + valueListenable: isSidebarOnHover, + builder: (_, value, ___) => Opacity( + opacity: value ? 1 : 0, + child: Padding( + padding: const EdgeInsets.only(top: 12.0, right: 4.0), + child: FlowyTooltip( + richMessage: textSpan, + child: Listener( + onPointerDown: (_) => context + .read() + .add(const HomeSettingEvent.collapseMenu()), + child: FlowyIconButton( + width: 24, + onPressed: () {}, + iconPadding: const EdgeInsets.all(4), + icon: const FlowySvg(FlowySvgs.hide_menu_s), + ), + ), + ), ), ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart index 0e49c2acd6..c27f259b68 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_folder.dart @@ -25,22 +25,21 @@ class SidebarFolder extends StatelessWidget { @override Widget build(BuildContext context) { + const sectionPadding = 16.0; return ValueListenableBuilder( valueListenable: getIt().notifier, builder: (context, value, child) { return Column( children: [ + const VSpace(4.0), // favorite BlocBuilder( builder: (context, state) { if (state.views.isEmpty) { return const SizedBox.shrink(); } - return Padding( - padding: const EdgeInsets.only(top: 16.0, bottom: 10), - child: FavoriteFolder( - views: state.views.map((e) => e.item).toList(), - ), + return FavoriteFolder( + views: state.views.map((e) => e.item).toList(), ); }, ), @@ -56,18 +55,18 @@ class SidebarFolder extends StatelessWidget { children: isCollaborativeWorkspace ? [ // public - const VSpace(10), + const VSpace(sectionPadding), PublicSectionFolder(views: state.section.publicViews), // private - const VSpace(10), + const VSpace(sectionPadding), PrivateSectionFolder( views: state.section.privateViews, ), ] : [ // personal - const VSpace(10), + const VSpace(sectionPadding), PersonalSectionFolder( views: state.section.publicViews, ), @@ -75,6 +74,7 @@ class SidebarFolder extends StatelessWidget { ); }, ), + const VSpace(200), ], ); }, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_new_page_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_new_page_button.dart index f58a1d43c9..b0b7b17483 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_new_page_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_new_page_button.dart @@ -18,20 +18,20 @@ class SidebarNewPageButton extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - padding: const EdgeInsets.symmetric(horizontal: 12), + padding: const EdgeInsets.symmetric(horizontal: 8), height: HomeSizes.newPageSectionHeight, child: FlowyButton( onTap: () async => _createNewPage(context), leftIcon: const FlowySvg( - FlowySvgs.new_app_s, + FlowySvgs.new_app_m, blendMode: null, ), - iconPadding: 10.0, - text: SizedBox( - height: 18.0, - child: FlowyText.regular( - LocaleKeys.newPageText.tr(), - ), + leftIconSize: const Size.square(24.0), + margin: const EdgeInsets.only(left: 4.0), + iconPadding: 8.0, + text: FlowyText.regular( + LocaleKeys.newPageText.tr(), + lineHeight: 1.15, ), ), ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart index 20c2338ebc..3e3610a653 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart @@ -1,12 +1,9 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/presentation/home/af_focus_manager.dart'; -import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/home/hotkeys.dart'; import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart'; import 'package:appflowy_backend/log.dart'; @@ -16,6 +13,7 @@ import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hotkey_manager/hotkey_manager.dart'; @@ -51,13 +49,15 @@ class UserSettingButton extends StatelessWidget { @override Widget build(BuildContext context) { return SizedBox.square( - dimension: HomeSizes.workspaceSectionHeight, + dimension: 24.0, child: FlowyTooltip( message: LocaleKeys.settings_menu_open.tr(), child: FlowyButton( onTap: () => showSettingsDialog(context, userProfile), + margin: EdgeInsets.zero, text: const FlowySvg( FlowySvgs.settings_s, + opacity: 0.7, ), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index 31cdf73685..c7d8e3fbc2 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -189,7 +189,8 @@ class _Sidebar extends StatefulWidget { class _SidebarState extends State<_Sidebar> { final _scrollController = ScrollController(); Timer? _scrollDebounce; - bool isScrolling = false; + bool _isScrolling = false; + final _isHovered = ValueNotifier(false); @override void initState() { @@ -202,79 +203,101 @@ class _SidebarState extends State<_Sidebar> { _scrollDebounce?.cancel(); _scrollController.removeListener(_onScrollChanged); _scrollController.dispose(); + _isHovered.dispose(); super.dispose(); } @override Widget build(BuildContext context) { - const menuHorizontalInset = EdgeInsets.symmetric(horizontal: 12); + const menuHorizontalInset = EdgeInsets.symmetric(horizontal: 8); final userState = context.read().state; - return DecoratedBox( - decoration: BoxDecoration( - color: Theme.of(context).colorScheme.surfaceContainerHighest, - border: Border( - right: BorderSide(color: Theme.of(context).dividerColor), - ), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // top menu - const Padding(padding: menuHorizontalInset, child: SidebarTopMenu()), - // user or workspace, setting - Container( - height: HomeSizes.workspaceSectionHeight, - padding: menuHorizontalInset - const EdgeInsets.only(right: 6), - child: - // if the workspaces are empty, show the user profile instead - userState.isCollabWorkspaceOn && userState.workspaces.isNotEmpty - ? SidebarWorkspace(userProfile: widget.userProfile) - : SidebarUser(userProfile: widget.userProfile), + return MouseRegion( + onEnter: (_) => _isHovered.value = true, + onExit: (_) => _isHovered.value = false, + child: DecoratedBox( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surfaceContainerHighest, + border: Border( + right: BorderSide(color: Theme.of(context).dividerColor), ), - if (FeatureFlag.search.isOn) ...[ - const VSpace(6), - Container( + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + // top menu + Padding( padding: menuHorizontalInset, - height: HomeSizes.searchSectionHeight, - child: const _SidebarSearchButton(), + child: SidebarTopMenu( + isSidebarOnHover: _isHovered, + ), ), - ], - // new page button - const SidebarNewPageButton(), - // scrollable document list - Expanded( - child: Padding( + // user or workspace, setting + Container( + height: HomeSizes.workspaceSectionHeight, padding: menuHorizontalInset - const EdgeInsets.only(right: 6), - child: SingleChildScrollView( - padding: const EdgeInsets.only(right: 6), - controller: _scrollController, - physics: const ClampingScrollPhysics(), - child: SidebarFolder( - userProfile: widget.userProfile, - isHoverEnabled: !isScrolling, + child: + // if the workspaces are empty, show the user profile instead + userState.isCollabWorkspaceOn && + userState.workspaces.isNotEmpty + ? SidebarWorkspace(userProfile: widget.userProfile) + : SidebarUser(userProfile: widget.userProfile), + ), + if (FeatureFlag.search.isOn) ...[ + const VSpace(6), + Container( + padding: menuHorizontalInset, + height: HomeSizes.searchSectionHeight, + child: const _SidebarSearchButton(), + ), + ], + const VSpace(6.0), + // new page button + const SidebarNewPageButton(), + // scrollable document list + const VSpace(12.0), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 12.0), + child: Divider( + color: Color(0x1E1F2329), + height: 0.5, + ), + ), + Expanded( + child: Padding( + padding: menuHorizontalInset - const EdgeInsets.only(right: 6), + child: SingleChildScrollView( + padding: const EdgeInsets.only(right: 6), + controller: _scrollController, + physics: const ClampingScrollPhysics(), + child: SidebarFolder( + userProfile: widget.userProfile, + isHoverEnabled: !_isScrolling, + ), ), ), ), - ), - const VSpace(10), - // trash - const Padding( - padding: menuHorizontalInset, - child: Divider(height: 1.0, color: Color(0x141F2329)), - ), - const VSpace(14), - const Padding( - padding: menuHorizontalInset, - child: SidebarFooter(), - ), - const VSpace(10), - ], + + // trash + Padding( + padding: menuHorizontalInset + + const EdgeInsets.symmetric(horizontal: 4.0), + child: const Divider(height: 1.0, color: Color(0x141F2329)), + ), + const VSpace(8), + Padding( + padding: menuHorizontalInset + + const EdgeInsets.symmetric(horizontal: 4.0), + child: const SidebarFooter(), + ), + const VSpace(14), + ], + ), ), ); } void _onScrollChanged() { - setState(() => isScrolling = true); + setState(() => _isScrolling = true); _scrollDebounce?.cancel(); _scrollDebounce = @@ -283,7 +306,7 @@ class _SidebarState extends State<_Sidebar> { void _setScrollStopped() { if (mounted) { - setState(() => isScrolling = false); + setState(() => _isScrolling = false); } } } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart index d179c4ce0f..6f96e6abc2 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart @@ -15,13 +15,17 @@ class WorkspaceIcon extends StatefulWidget { required this.iconSize, required this.fontSize, required this.onSelected, + this.borderRadius = 4, + this.emojiSize, }); final UserWorkspacePB workspace; final double iconSize; final bool enableEdit; final double fontSize; + final double? emojiSize; final void Function(EmojiPickerResult) onSelected; + final double borderRadius; @override State createState() => _WorkspaceIconState(); @@ -38,18 +42,22 @@ class _WorkspaceIconState extends State { alignment: Alignment.center, child: FlowyText.emoji( widget.workspace.icon, - fontSize: widget.iconSize, + fontSize: widget.emojiSize ?? widget.iconSize, ), ) : Container( alignment: Alignment.center, width: widget.iconSize, - height: min(widget.iconSize, 26), + height: min(widget.iconSize, 24), decoration: BoxDecoration( color: ColorGenerator(widget.workspace.name).toColor(), - borderRadius: BorderRadius.circular(4), + borderRadius: BorderRadius.circular(widget.borderRadius), + border: Border.all( + color: const Color(0xa1717171), + width: 0.5, + ), ), - child: FlowyText( + child: FlowyText.semibold( widget.workspace.name.isEmpty ? '' : widget.workspace.name.substring(0, 1), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart index d1a09afc28..1dddce8ac6 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart @@ -1,4 +1,3 @@ -import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/openai/widgets/loading.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; @@ -49,7 +48,9 @@ class _SidebarWorkspaceState extends State { ), ), UserSettingButton(userProfile: widget.userProfile), + const HSpace(8.0), const NotificationButton(), + const HSpace(10.0), ], ); }, @@ -203,12 +204,14 @@ class _SidebarSwitchWorkspaceButtonState height: 30, child: Row( children: [ - const HSpace(6.0), + const HSpace(4.0), WorkspaceIcon( workspace: widget.currentWorkspace, - iconSize: 16, - fontSize: 10, + iconSize: 24, + fontSize: 16, + emojiSize: 18, enableEdit: false, + borderRadius: 8.0, onSelected: (result) => context.read().add( UserWorkspaceEvent.updateWorkspaceIcon( widget.currentWorkspace.workspaceId, @@ -216,23 +219,16 @@ class _SidebarSwitchWorkspaceButtonState ), ), ), - const HSpace(10), + const HSpace(8), Flexible( child: FlowyText.medium( widget.currentWorkspace.name, overflow: TextOverflow.ellipsis, withTooltip: true, + fontSize: 15.0, ), ), const HSpace(4), - ValueListenableBuilder( - valueListenable: _isWorkSpaceMenuExpanded, - builder: (context, value, _) => FlowySvg( - value - ? FlowySvgs.workspace_drop_down_menu_hide_s - : FlowySvgs.workspace_drop_down_menu_show_s, - ), - ), ], ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_add_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_add_button.dart index 1cfff3c6e6..3fa23c8f1c 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_add_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_add_button.dart @@ -50,10 +50,12 @@ class ViewAddButton extends StatelessWidget { return PopoverActionList( direction: PopoverDirection.bottomWithLeftAligned, actions: _actions, - offset: const Offset(0, 4), + offset: const Offset(0, 8), + constraints: const BoxConstraints( + minWidth: 200, + ), buildChild: (popover) { return FlowyIconButton( - hoverColor: Colors.transparent, width: 24, icon: const FlowySvg(FlowySvgs.view_item_add_s), onPressed: () { @@ -122,7 +124,7 @@ class ViewImportActionWrapper extends ActionCell { final DocumentPluginBuilder pluginBuilder; @override - Widget? leftIcon(Color iconColor) => const FlowySvg(FlowySvgs.import_s); + Widget? leftIcon(Color iconColor) => const FlowySvg(FlowySvgs.icon_import_s); @override String get name => LocaleKeys.moreAction_import.tr(); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart index 1e58b7703f..cdbbd76e33 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart @@ -422,20 +422,19 @@ class _SingleInnerViewItemState extends State { Widget _buildViewItem(bool onHover, [bool isSelected = false]) { final children = [ + const HSpace(2), // expand icon or placeholder widget.leftIconBuilder?.call(context, widget.view) ?? _buildLeftIcon(), + const HSpace(2), // icon _buildViewIconButton(), const HSpace(6), - // const SizedBox( - // width: 6.0, - // height: 1, - // ), // title Expanded( child: FlowyText.regular( widget.view.name, overflow: TextOverflow.ellipsis, + lineHeight: 1.1, ), ), ]; @@ -447,10 +446,10 @@ class _SingleInnerViewItemState extends State { } else { // ··· more action button children.add(_buildViewMoreActionButton(context)); - children.add(const HSpace(8.0)); // only support add button for document layout if (widget.view.layout == ViewLayoutPB.Document) { // + button + children.add(const HSpace(8.0)); children.add(_buildViewAddButton(context)); } children.add(const HSpace(4.0)); @@ -500,8 +499,9 @@ class _SingleInnerViewItemState extends State { ? FlowyText.emoji( widget.view.icon.value, fontSize: 16.0, + lineHeight: 1.4, ) - : widget.view.defaultIcon(); + : Opacity(opacity: 0.6, child: widget.view.defaultIcon()); return AppFlowyPopover( offset: const Offset(20, 0), @@ -545,16 +545,18 @@ class _SingleInnerViewItemState extends State { return HSpace(widget.leftPadding); } - final child = GestureDetector( - child: FlowySvg( - widget.isExpanded - ? FlowySvgs.view_item_expand_s - : FlowySvgs.view_item_unexpand_s, - size: const Size.square(16.0), + final child = FlowyHover( + child: GestureDetector( + child: FlowySvg( + widget.isExpanded + ? FlowySvgs.view_item_expand_s + : FlowySvgs.view_item_unexpand_s, + size: const Size.square(16.0), + ), + onTap: () => context + .read() + .add(ViewEvent.setIsExpanded(!widget.isExpanded)), ), - onTap: () => context - .read() - .add(ViewEvent.setIsExpanded(!widget.isExpanded)), ); if (widget.isHovered != null) { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart index 4201ec5396..55503cd38d 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/navigation.dart @@ -91,13 +91,16 @@ class FlowyNavigation extends StatelessWidget { turns: const AlwaysStoppedAnimation(180 / 360), child: FlowyTooltip( richMessage: textSpan, - child: FlowyIconButton( - width: 24, - onPressed: () => context + child: Listener( + onPointerDown: (event) => context .read() .add(const HomeSettingEvent.collapseMenu()), - iconPadding: const EdgeInsets.all(2), - icon: const FlowySvg(FlowySvgs.hide_menu_s), + child: FlowyIconButton( + width: 24, + onPressed: () {}, + iconPadding: const EdgeInsets.all(4), + icon: const FlowySvg(FlowySvgs.hide_menu_s), + ), ), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart index 08f421951b..e28ebfb1c2 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart @@ -4,7 +4,6 @@ import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart'; -import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/notifications/notification_dialog.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -43,9 +42,10 @@ class NotificationButton extends StatelessWidget { popupBuilder: (_) => NotificationDialog(views: views, mutex: mutex), child: SizedBox.square( - dimension: HomeSizes.workspaceSectionHeight, + dimension: 24.0, child: FlowyButton( useIntrinsicWidth: true, + margin: EdgeInsets.zero, text: _buildNotificationIcon(context, state.hasUnreads), ), @@ -62,8 +62,11 @@ class NotificationButton extends StatelessWidget { Widget _buildNotificationIcon(BuildContext context, bool hasUnreads) { return Stack( children: [ - const FlowySvg( - FlowySvgs.notification_s, + const Center( + child: FlowySvg( + FlowySvgs.notification_s, + opacity: 0.7, + ), ), if (hasUnreads) Positioned( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart index 970ee82631..68e8073db3 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/favorite_button.dart @@ -33,8 +33,9 @@ class ViewFavoriteButton extends StatelessWidget { child: Padding( padding: const EdgeInsets.all(6), child: FlowySvg( - isFavorite ? FlowySvgs.unfavorite_s : FlowySvgs.favorite_s, + isFavorite ? FlowySvgs.favorited_s : FlowySvgs.favorite_s, size: const Size.square(18), + blendMode: null, ), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart index 1c8c8d20ff..fde71f9150 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/float_bubble/question_bubble.dart @@ -2,14 +2,14 @@ import 'package:appflowy/core/helpers/url_launcher.dart'; import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/tasks/rust_sdk.dart'; +import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/workspace/presentation/home/toast.dart'; import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:easy_localization/easy_localization.dart'; -import 'package:flowy_infra/size.dart'; -import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -21,9 +21,8 @@ class QuestionBubble extends StatelessWidget { @override Widget build(BuildContext context) { - return const SizedBox( - width: 30, - height: 30, + return const SizedBox.square( + dimension: 36.0, child: BubbleActionList(), ); } @@ -61,24 +60,55 @@ class _BubbleActionListState extends State { ); actions.add(FlowyVersionDescription()); + final (color, borderColor, shadowColor, iconColor) = + Theme.of(context).isLightMode + ? ( + Colors.white, + const Color(0x2D454849), + const Color(0x14000000), + Colors.black, + ) + : ( + const Color(0xFF242B37), + const Color(0x2DFFFFFF), + const Color(0x14000000), + Colors.white, + ); + return PopoverActionList( direction: PopoverDirection.topWithRightAligned, actions: actions, offset: const Offset(0, -8), buildChild: (controller) { - return FlowyTextButton( - '?', - tooltip: LocaleKeys.questionBubble_help.tr(), - fontWeight: FontWeight.w600, - fontColor: fontColor, - fillColor: fillColor, - hoverColor: Theme.of(context).colorScheme.primary, - mainAxisAlignment: MainAxisAlignment.center, - radius: Corners.s10Border, - onPressed: () { - toggle(); - controller.show(); - }, + return FlowyTooltip( + message: LocaleKeys.questionBubble_help.tr(), + child: MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + child: Container( + padding: const EdgeInsets.all(10.0), + decoration: ShapeDecoration( + color: color, + shape: RoundedRectangleBorder( + side: BorderSide(width: 0.50, color: borderColor), + borderRadius: BorderRadius.circular(18), + ), + shadows: [ + BoxShadow( + color: shadowColor, + blurRadius: 20, + offset: const Offset(0, 8), + ), + ], + ), + child: FlowySvg( + FlowySvgs.help_center_s, + color: iconColor, + ), + ), + onTap: () => controller.show(), + ), + ), ); }, onClosed: toggle, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/pop_up_action.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/pop_up_action.dart index d4103cc6bf..6abc789223 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/pop_up_action.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/pop_up_action.dart @@ -245,9 +245,10 @@ class HoverButton extends StatelessWidget { HSpace(ActionListSizes.itemHPadding), ], Expanded( - child: FlowyText.medium( + child: FlowyText.regular( name, overflow: TextOverflow.visible, + lineHeight: 1.15, ), ), if (rightIcon != null) ...[ diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart index b3eddfb52b..18dc91de58 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/view_title_bar.dart @@ -33,6 +33,7 @@ class ViewTitleBar extends StatelessWidget { return const SizedBox.shrink(); } return SingleChildScrollView( + scrollDirection: Axis.horizontal, child: SizedBox( height: 24, child: Row(children: _buildViewTitles(context, ancestors)), @@ -165,11 +166,14 @@ class _ViewTitleState extends State<_ViewTitle> { Widget _buildUnEditableViewTitle(BuildContext context, ViewTitleState state) { return Listener( onPointerDown: (_) => context.read().openPlugin(widget.view), - child: FlowyButton( - useIntrinsicWidth: true, - margin: const EdgeInsets.symmetric(horizontal: 6.0), - onTap: () {}, - text: _buildIconAndName(state), + child: SizedBox( + height: 32.0, + child: FlowyButton( + useIntrinsicWidth: true, + margin: const EdgeInsets.symmetric(horizontal: 6.0), + onTap: () {}, + text: _buildIconAndName(state, false), + ), ), ); } @@ -194,15 +198,18 @@ class _ViewTitleState extends State<_ViewTitle> { emoji: state.icon, ); }, - child: FlowyButton( - useIntrinsicWidth: true, - margin: const EdgeInsets.symmetric(horizontal: 6.0), - text: _buildIconAndName(state), + child: SizedBox( + height: 32.0, + child: FlowyButton( + useIntrinsicWidth: true, + margin: const EdgeInsets.symmetric(horizontal: 6.0), + text: _buildIconAndName(state, true), + ), ), ); } - Widget _buildIconAndName(ViewTitleState state) { + Widget _buildIconAndName(ViewTitleState state, bool isEditable) { return SingleChildScrollView( child: Row( children: [ @@ -211,10 +218,10 @@ class _ViewTitleState extends State<_ViewTitle> { state.icon, fontSize: 14.0, ), - const HSpace(6.0), + const HSpace(4.0), ], - ConstrainedBox( - constraints: const BoxConstraints(), + Opacity( + opacity: isEditable ? 1.0 : 0.5, child: FlowyText.regular( state.name, overflow: TextOverflow.ellipsis, diff --git a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart index 8f7120fa84..81142383c1 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra/lib/colorscheme/default_colorscheme.dart @@ -6,19 +6,19 @@ const _white = Color(0xFFFFFFFF); const _lightHover = Color(0xFFe0f8FF); const _lightSelector = Color(0xFFf2fcFF); const _lightBg1 = Color(0xFFf7f8fc); -const _lightBg2 = Color(0xFFedeef2); +const _lightBg2 = Color(0x0F1F2329); const _lightShader1 = Color(0xFF333333); const _lightShader3 = Color(0xFF828282); const _lightShader5 = Color(0xFFe0e0e0); const _lightShader6 = Color(0xFFf2f2f2); const _lightMain1 = Color(0xFF00bcf0); const _lightTint9 = Color(0xFFe1fbFF); -const _darkShader1 = Color(0xE5FFFFFF); +const _darkShader1 = Color(0xFF131720); const _darkShader2 = Color(0xFF1A202C); const _darkShader3 = Color(0xFF363D49); const _darkShader5 = Color(0xFFBBC3CD); const _darkShader6 = Color(0xFFF2F2F2); -const _darkMain1 = Color(0x19FFFFFF); +const _darkMain1 = Color(0xFF00BCF0); const _darkMain2 = Color(0xFF00BCF0); const _darkInput = Color(0xFF282E3A); diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart index 10065b3dc7..d5d04ddb98 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart @@ -166,7 +166,6 @@ class FlowyText extends StatelessWidget { text, maxLines: maxLines, textAlign: textAlign, - strutStyle: strutStyle, style: textStyle, ); } else { diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart index 57874fad64..382b18fc0e 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart @@ -25,6 +25,7 @@ class FlowyTooltip extends StatelessWidget { final isLightMode = Theme.of(context).brightness == Brightness.light; return Tooltip( margin: margin, + padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0), decoration: BoxDecoration( color: isLightMode ? const Color(0xE5171717) : const Color(0xE5E5E5E5), borderRadius: BorderRadius.circular(8.0), diff --git a/frontend/appflowy_flutter/packages/flowy_svg/lib/src/flowy_svg.dart b/frontend/appflowy_flutter/packages/flowy_svg/lib/src/flowy_svg.dart index baf08538b8..aa70ee9d1f 100644 --- a/frontend/appflowy_flutter/packages/flowy_svg/lib/src/flowy_svg.dart +++ b/frontend/appflowy_flutter/packages/flowy_svg/lib/src/flowy_svg.dart @@ -23,6 +23,7 @@ class FlowySvg extends StatelessWidget { this.size, this.color, this.blendMode = BlendMode.srcIn, + this.opacity = 1.0, }); /// The data for the flowy svg. Will be generated by the generator in this @@ -46,11 +47,16 @@ class FlowySvg extends StatelessWidget { /// svg widget. final BlendMode? blendMode; + /// The opacity of the svg + /// + /// The default value is 1.0 + final double opacity; + @override Widget build(BuildContext context) { - final iconColor = color ?? Theme.of(context).iconTheme.color; + final iconColor = + (color ?? Theme.of(context).iconTheme.color)?.withOpacity(opacity); final textScaleFactor = MediaQuery.textScalerOf(context).scale(1); - return Transform.scale( scale: textScaleFactor, child: SizedBox( diff --git a/frontend/resources/flowy_icons/16x/favorited.svg b/frontend/resources/flowy_icons/16x/favorited.svg new file mode 100644 index 0000000000..a17f7548cd --- /dev/null +++ b/frontend/resources/flowy_icons/16x/favorited.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/flowy_icons/16x/help_center.svg b/frontend/resources/flowy_icons/16x/help_center.svg new file mode 100644 index 0000000000..52766922e9 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/help_center.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/frontend/resources/flowy_icons/16x/icon_board.svg b/frontend/resources/flowy_icons/16x/icon_board.svg new file mode 100644 index 0000000000..9133d535b5 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/icon_board.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/16x/icon_calendar.svg b/frontend/resources/flowy_icons/16x/icon_calendar.svg new file mode 100644 index 0000000000..ca65315d3c --- /dev/null +++ b/frontend/resources/flowy_icons/16x/icon_calendar.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/flowy_icons/16x/icon_document.svg b/frontend/resources/flowy_icons/16x/icon_document.svg new file mode 100644 index 0000000000..75acd9a2a3 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/icon_document.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/resources/flowy_icons/16x/icon_grid.svg b/frontend/resources/flowy_icons/16x/icon_grid.svg new file mode 100644 index 0000000000..a167a4a6ad --- /dev/null +++ b/frontend/resources/flowy_icons/16x/icon_grid.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/flowy_icons/16x/icon_import.svg b/frontend/resources/flowy_icons/16x/icon_import.svg new file mode 100644 index 0000000000..bc8d7c7b72 --- /dev/null +++ b/frontend/resources/flowy_icons/16x/icon_import.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/16x/workspace_drop_down_menu_hide.svg b/frontend/resources/flowy_icons/16x/workspace_drop_down_menu_hide.svg index d264b4734e..f6c5884f5b 100644 --- a/frontend/resources/flowy_icons/16x/workspace_drop_down_menu_hide.svg +++ b/frontend/resources/flowy_icons/16x/workspace_drop_down_menu_hide.svg @@ -1,8 +1,3 @@ - - - - - - - + + diff --git a/frontend/resources/flowy_icons/16x/workspace_drop_down_menu_show.svg b/frontend/resources/flowy_icons/16x/workspace_drop_down_menu_show.svg index 4682de7aa7..80ce09be81 100644 --- a/frontend/resources/flowy_icons/16x/workspace_drop_down_menu_show.svg +++ b/frontend/resources/flowy_icons/16x/workspace_drop_down_menu_show.svg @@ -1,8 +1,3 @@ - - - - - - - + + diff --git a/frontend/resources/flowy_icons/24x/favorite_header_icon.svg b/frontend/resources/flowy_icons/24x/favorite_header_icon.svg new file mode 100644 index 0000000000..5b0ddbb6c5 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/favorite_header_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/resources/flowy_icons/24x/new_app.svg b/frontend/resources/flowy_icons/24x/new_app.svg new file mode 100644 index 0000000000..77b11173d8 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/new_app.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/frontend/resources/flowy_icons/24x/sidebar_footer_trash.svg b/frontend/resources/flowy_icons/24x/sidebar_footer_trash.svg new file mode 100644 index 0000000000..02122ae127 --- /dev/null +++ b/frontend/resources/flowy_icons/24x/sidebar_footer_trash.svg @@ -0,0 +1,9 @@ + + + + + + + + + From 1e485188ebef64ba6d244122dceb6bdae613276c Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 4 Jun 2024 09:28:28 +0800 Subject: [PATCH 03/11] fix: font not found error log (#5449) * fix: font not found error log * fix: flutter analyze --- .../document/presentation/editor_style.dart | 3 +-- .../lib/shared/google_fonts_extension.dart | 1 - .../settings/appearance/appearance_cubit.dart | 6 +----- .../settings/appearance/base_appearance.dart | 5 +---- .../app_setting_test/appearance_test.dart | 1 - .../test/widget_test/direction_setting_test.dart | 15 +++++++-------- 6 files changed, 10 insertions(+), 21 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart index 0b3aca1ce7..bc48ddf8a2 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_style.dart @@ -237,8 +237,7 @@ class EditorStyleCustomizer { try { return getGoogleFontSafely(fontFamily, fontWeight: fontWeight); } on Exception { - if ([defaultFontFamily, fallbackFontFamily, builtInCodeFontFamily] - .contains(fontFamily)) { + if ([defaultFontFamily, builtInCodeFontFamily].contains(fontFamily)) { return TextStyle(fontFamily: fontFamily, fontWeight: fontWeight); } diff --git a/frontend/appflowy_flutter/lib/shared/google_fonts_extension.dart b/frontend/appflowy_flutter/lib/shared/google_fonts_extension.dart index 287bfcbcd9..c5cb5df786 100644 --- a/frontend/appflowy_flutter/lib/shared/google_fonts_extension.dart +++ b/frontend/appflowy_flutter/lib/shared/google_fonts_extension.dart @@ -6,7 +6,6 @@ import 'package:google_fonts/google_fonts.dart'; const _defaultFontFamilies = [ defaultFontFamily, builtInCodeFontFamily, - fallbackFontFamily, ]; // if the font family is not available, google fonts packages will throw an exception diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/appearance_cubit.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/appearance_cubit.dart index fa9b571478..a034558110 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/appearance_cubit.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/appearance_cubit.dart @@ -41,7 +41,6 @@ class AppearanceSettingsCubit extends Cubit { appTheme, appearanceSettings.themeMode, appearanceSettings.font, - appearanceSettings.monospaceFont, appearanceSettings.layoutDirection, appearanceSettings.textDirection, appearanceSettings.enableRtlToolbarItems, @@ -374,7 +373,6 @@ class AppearanceSettingsState with _$AppearanceSettingsState { required AppTheme appTheme, required ThemeMode themeMode, required String font, - required String monospaceFont, required LayoutDirection layoutDirection, required AppFlowyTextDirection? textDirection, required bool enableRtlToolbarItems, @@ -393,7 +391,6 @@ class AppearanceSettingsState with _$AppearanceSettingsState { AppTheme appTheme, ThemeModePB themeModePB, String font, - String monospaceFont, LayoutDirectionPB layoutDirectionPB, TextDirectionPB? textDirectionPB, bool enableRtlToolbarItems, @@ -410,7 +407,6 @@ class AppearanceSettingsState with _$AppearanceSettingsState { return AppearanceSettingsState( appTheme: appTheme, font: font, - monospaceFont: monospaceFont, layoutDirection: LayoutDirection.fromLayoutDirectionPB(layoutDirectionPB), textDirection: AppFlowyTextDirection.fromTextDirectionPB(textDirectionPB), enableRtlToolbarItems: enableRtlToolbarItems, @@ -435,7 +431,7 @@ class AppearanceSettingsState with _$AppearanceSettingsState { appTheme, brightness, font, - monospaceFont, + builtInCodeFontFamily, ); } } diff --git a/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/base_appearance.dart b/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/base_appearance.dart index 0c6fe9aaed..952f1e18f9 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/base_appearance.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/settings/appearance/base_appearance.dart @@ -11,9 +11,6 @@ import 'package:flutter/material.dart'; // Desktop: Based on the OS const defaultFontFamily = ''; -// the Poppins font is embedded in the app, so we can use it without GoogleFonts -// TODO(Lucas): after releasing version 0.5.6, remove it. -const fallbackFontFamily = 'Poppins'; const builtInCodeFontFamily = 'RobotoMono'; abstract class BaseAppearance { @@ -47,7 +44,7 @@ abstract class BaseAppearance { height: lineHeight, ); - if (fontFamily == defaultFontFamily || fontFamily == fallbackFontFamily) { + if (fontFamily == defaultFontFamily) { return textStyle; } diff --git a/frontend/appflowy_flutter/test/bloc_test/app_setting_test/appearance_test.dart b/frontend/appflowy_flutter/test/bloc_test/app_setting_test/appearance_test.dart index 4f8f4b786a..d9cd57757e 100644 --- a/frontend/appflowy_flutter/test/bloc_test/app_setting_test/appearance_test.dart +++ b/frontend/appflowy_flutter/test/bloc_test/app_setting_test/appearance_test.dart @@ -37,7 +37,6 @@ void main() { ), verify: (bloc) { expect(bloc.state.font, defaultFontFamily); - expect(bloc.state.monospaceFont, 'SF Mono'); expect(bloc.state.themeMode, ThemeMode.system); }, ); diff --git a/frontend/appflowy_flutter/test/widget_test/direction_setting_test.dart b/frontend/appflowy_flutter/test/widget_test/direction_setting_test.dart index 34472193f9..d83706f068 100644 --- a/frontend/appflowy_flutter/test/widget_test/direction_setting_test.dart +++ b/frontend/appflowy_flutter/test/widget_test/direction_setting_test.dart @@ -1,17 +1,17 @@ -import 'package:appflowy/workspace/presentation/settings/pages/settings_workspace_view.dart'; -import 'package:appflowy/workspace/presentation/settings/shared/settings_radio_select.dart'; -import 'package:flowy_infra/theme.dart'; -import 'package:flutter/material.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; +import 'package:appflowy/user/application/user_settings_service.dart'; import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart'; +import 'package:appflowy/workspace/presentation/settings/pages/settings_workspace_view.dart'; +import 'package:appflowy/workspace/presentation/settings/shared/settings_radio_select.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart'; +import 'package:bloc_test/bloc_test.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra/theme.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; -import 'package:bloc_test/bloc_test.dart'; -import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart'; -import 'package:appflowy/user/application/user_settings_service.dart'; import '../util.dart'; @@ -41,7 +41,6 @@ void main() { AppTheme.fallback, appearanceSettings.themeMode, appearanceSettings.font, - appearanceSettings.monospaceFont, appearanceSettings.layoutDirection, appearanceSettings.textDirection, appearanceSettings.enableRtlToolbarItems, From 57d4652824418b6c1243d8656ec3afd72ce80304 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 4 Jun 2024 11:37:06 +0800 Subject: [PATCH 04/11] fix: some keys conflict with board shortcuts (#5460) --- .../board/presentation/board_page.dart | 113 +++++++++--------- .../widgets/board_column_header.dart | 12 +- .../widgets/board_shortcut_container.dart | 11 +- .../plugins/shared/callback_shortcuts.dart | 48 ++++++++ 4 files changed, 125 insertions(+), 59 deletions(-) create mode 100644 frontend/appflowy_flutter/lib/plugins/shared/callback_shortcuts.dart diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart index a1f3a78f75..a32abd33aa 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/board_page.dart @@ -14,6 +14,7 @@ import 'package:appflowy/plugins/database/tab_bar/tab_bar_view.dart'; import 'package:appflowy/plugins/database/widgets/card/card_bloc.dart'; import 'package:appflowy/plugins/database/widgets/cell/card_cell_style_maps/desktop_board_card_cell_style.dart'; import 'package:appflowy/plugins/database/widgets/row/row_detail.dart'; +import 'package:appflowy/plugins/shared/callback_shortcuts.dart'; import 'package:appflowy/shared/conditional_listenable_builder.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; @@ -28,6 +29,7 @@ import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flutter/material.dart' hide Card; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:provider/provider.dart'; import '../../widgets/card/card.dart'; import '../../widgets/cell/card_cell_builder.dart'; @@ -320,64 +322,67 @@ class _BoardContentState extends State<_BoardContent> { }, ), ], - child: FocusScope( - autofocus: true, - child: BoardShortcutContainer( - focusScope: widget.focusScope, - child: Padding( - padding: const EdgeInsets.only(top: 8.0), - child: AppFlowyBoard( - boardScrollController: scrollManager, - scrollController: scrollController, - controller: context.read().boardController, - groupConstraints: const BoxConstraints.tightFor(width: 256), - config: config, - leading: HiddenGroupsColumn(margin: config.groupHeaderPadding), - trailing: context - .read() - .groupingFieldType - ?.canCreateNewGroup ?? - false - ? BoardTrailing(scrollController: scrollController) - : const HSpace(40), - headerBuilder: (_, groupData) => BlocProvider.value( - value: context.read(), - child: BoardColumnHeader( - groupData: groupData, - margin: config.groupHeaderPadding, + child: Provider( + create: (context) => AFCallbackShortcutsProvider(), + child: FocusScope( + autofocus: true, + child: BoardShortcutContainer( + focusScope: widget.focusScope, + child: Padding( + padding: const EdgeInsets.only(top: 8.0), + child: AppFlowyBoard( + boardScrollController: scrollManager, + scrollController: scrollController, + controller: context.read().boardController, + groupConstraints: const BoxConstraints.tightFor(width: 256), + config: config, + leading: HiddenGroupsColumn(margin: config.groupHeaderPadding), + trailing: context + .read() + .groupingFieldType + ?.canCreateNewGroup ?? + false + ? BoardTrailing(scrollController: scrollController) + : const HSpace(40), + headerBuilder: (_, groupData) => BlocProvider.value( + value: context.read(), + child: BoardColumnHeader( + groupData: groupData, + margin: config.groupHeaderPadding, + ), ), - ), - footerBuilder: (_, groupData) => MultiBlocProvider( - providers: [ - BlocProvider.value( - value: context.read(), + footerBuilder: (_, groupData) => MultiBlocProvider( + providers: [ + BlocProvider.value( + value: context.read(), + ), + BlocProvider.value( + value: context.read(), + ), + ], + child: BoardColumnFooter( + columnData: groupData, + boardConfig: config, + scrollManager: scrollManager, ), - BlocProvider.value( - value: context.read(), - ), - ], - child: BoardColumnFooter( - columnData: groupData, - boardConfig: config, - scrollManager: scrollManager, ), - ), - cardBuilder: (_, column, columnItem) => MultiBlocProvider( - key: ValueKey("board_card_${column.id}_${columnItem.id}"), - providers: [ - BlocProvider.value( - value: context.read(), + cardBuilder: (_, column, columnItem) => MultiBlocProvider( + key: ValueKey("board_card_${column.id}_${columnItem.id}"), + providers: [ + BlocProvider.value( + value: context.read(), + ), + BlocProvider.value( + value: context.read(), + ), + ], + child: _BoardCard( + afGroupData: column, + groupItem: columnItem as GroupItem, + boardConfig: config, + notifier: widget.focusScope, + cellBuilder: cellBuilder, ), - BlocProvider.value( - value: context.read(), - ), - ], - child: _BoardCard( - afGroupData: column, - groupItem: columnItem as GroupItem, - boardConfig: config, - notifier: widget.focusScope, - cellBuilder: cellBuilder, ), ), ), diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_column_header.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_column_header.dart index ff06319f73..53cd3c1e4f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_column_header.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_column_header.dart @@ -3,6 +3,7 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/board/application/board_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/header/field_type_extension.dart'; +import 'package:appflowy/plugins/shared/callback_shortcuts.dart'; import 'package:appflowy/workspace/presentation/widgets/dialogs.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_board/appflowy_board.dart'; @@ -30,6 +31,8 @@ class BoardColumnHeader extends StatefulWidget { class _BoardColumnHeaderState extends State { final FocusNode _focusNode = FocusNode(); + final FocusNode _keyboardListenerFocusNode = FocusNode(); + late final AFCallbackShortcutsProvider _shortcutsProvider; late final TextEditingController _controller = TextEditingController.fromValue( @@ -44,16 +47,23 @@ class _BoardColumnHeaderState extends State { @override void initState() { super.initState(); + _shortcutsProvider = context.read(); _focusNode.addListener(() { if (!_focusNode.hasFocus) { _saveEdit(); } }); + _keyboardListenerFocusNode.addListener(() { + _shortcutsProvider.isShortcutsEnabled.value = + !_keyboardListenerFocusNode.hasFocus; + }); } @override void dispose() { + _shortcutsProvider.isShortcutsEnabled.value = true; _focusNode.dispose(); + _keyboardListenerFocusNode.dispose(); _controller.dispose(); super.dispose(); } @@ -149,7 +159,7 @@ class _BoardColumnHeaderState extends State { Widget _buildTextField(BuildContext context) { return Expanded( child: KeyboardListener( - focusNode: FocusNode(), + focusNode: _keyboardListenerFocusNode, onKeyEvent: (event) { if ([LogicalKeyboardKey.enter, LogicalKeyboardKey.escape] .contains(event.logicalKey)) { diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_shortcut_container.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_shortcut_container.dart index 022c25ff18..1035364702 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_shortcut_container.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_shortcut_container.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:appflowy/plugins/database/board/application/board_actions_bloc.dart'; import 'package:appflowy/plugins/database/board/application/board_bloc.dart'; +import 'package:appflowy/plugins/shared/callback_shortcuts.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -20,7 +21,9 @@ class BoardShortcutContainer extends StatelessWidget { @override Widget build(BuildContext context) { - return CallbackShortcuts( + return AFCallbackShortcuts( + canAcceptEvent: (_, __) => + context.read().isShortcutsEnabled.value, bindings: { const SingleActivator(LogicalKeyboardKey.arrowUp): focusScope.focusPrevious, @@ -93,9 +96,9 @@ class BoardShortcutContainer extends StatelessWidget { if (focusScope.value.length != 1) { return; } - context - .read() - .openCardWithRowId(focusScope.value.first.rowId); + context + .read() + .openCardWithRowId(focusScope.value.first.rowId); } void _shitEnterHandler(BuildContext context) { diff --git a/frontend/appflowy_flutter/lib/plugins/shared/callback_shortcuts.dart b/frontend/appflowy_flutter/lib/plugins/shared/callback_shortcuts.dart new file mode 100644 index 0000000000..26e188511e --- /dev/null +++ b/frontend/appflowy_flutter/lib/plugins/shared/callback_shortcuts.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class AFCallbackShortcutsProvider { + final ValueNotifier isShortcutsEnabled = ValueNotifier(true); +} + +class AFCallbackShortcuts extends StatelessWidget { + const AFCallbackShortcuts({ + super.key, + required this.bindings, + required this.canAcceptEvent, + required this.child, + }); + + final Map bindings; + final bool Function(FocusNode node, KeyEvent event) canAcceptEvent; + final Widget child; + + bool _applyKeyEventBinding(ShortcutActivator activator, KeyEvent event) { + if (activator.accepts(event, HardwareKeyboard.instance)) { + bindings[activator]!.call(); + return true; + } + return false; + } + + @override + Widget build(BuildContext context) { + return Focus( + canRequestFocus: false, + skipTraversal: true, + onKeyEvent: (FocusNode node, KeyEvent event) { + if (!canAcceptEvent(node, event)) { + return KeyEventResult.ignored; + } + KeyEventResult result = KeyEventResult.ignored; + for (final ShortcutActivator activator in bindings.keys) { + result = _applyKeyEventBinding(activator, event) + ? KeyEventResult.handled + : result; + } + return result; + }, + child: child, + ); + } +} From 17575703379b6129f0e11952b88197360ce84b89 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Tue, 4 Jun 2024 15:59:56 +0800 Subject: [PATCH 05/11] feat: change user avatar corner radius (#5461) --- .../menu/sidebar/header/sidebar_user.dart | 18 ++++-- .../presentation/widgets/user_avatar.dart | 63 ++++++++++--------- 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_user.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_user.dart index 20465d0faa..524934aa82 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_user.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_user.dart @@ -28,17 +28,26 @@ class SidebarUser extends StatelessWidget { child: BlocBuilder( builder: (context, state) => Row( children: [ - const HSpace(6), + const HSpace(4), UserAvatar( iconUrl: state.userProfile.iconUrl, name: state.userProfile.name, - size: 16.0, - fontSize: 10.0, + size: 24.0, + fontSize: 16.0, + decoration: ShapeDecoration( + color: const Color(0xFFFBE8FB), + shape: RoundedRectangleBorder( + side: const BorderSide(width: 0.50, color: Color(0x19171717)), + borderRadius: BorderRadius.circular(8), + ), + ), ), - const HSpace(10), + const HSpace(8), Expanded(child: _buildUserName(context, state)), UserSettingButton(userProfile: state.userProfile), + const HSpace(8.0), const NotificationButton(), + const HSpace(10.0), ], ), ), @@ -51,6 +60,7 @@ class SidebarUser extends StatelessWidget { name, overflow: TextOverflow.ellipsis, color: Theme.of(context).colorScheme.tertiary, + fontSize: 15.0, ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart index 357e565559..adb3b1e454 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/widgets/user_avatar.dart @@ -16,12 +16,14 @@ class UserAvatar extends StatelessWidget { required this.size, required this.fontSize, this.isHovering = false, + this.decoration, }); final String iconUrl; final String name; final double size; final double fontSize; + final Decoration? decoration; // If true, a border will be applied on top of the avatar final bool isHovering; @@ -54,17 +56,18 @@ class UserAvatar extends StatelessWidget { width: size, height: size, alignment: Alignment.center, - decoration: BoxDecoration( - color: color, - shape: BoxShape.circle, - border: isHovering - ? Border.all( - color: _darken(color), - width: 4, - ) - : null, - ), - child: FlowyText.regular( + decoration: decoration ?? + BoxDecoration( + color: color, + shape: BoxShape.circle, + border: isHovering + ? Border.all( + color: _darken(color), + width: 4, + ) + : null, + ), + child: FlowyText.medium( nameInitials, color: Colors.black, fontSize: fontSize, @@ -76,15 +79,16 @@ class UserAvatar extends StatelessWidget { return SizedBox.square( dimension: size, child: DecoratedBox( - decoration: BoxDecoration( - shape: BoxShape.circle, - border: isHovering - ? Border.all( - color: Theme.of(context).colorScheme.primary, - width: 4, - ) - : null, - ), + decoration: decoration ?? + BoxDecoration( + shape: BoxShape.circle, + border: isHovering + ? Border.all( + color: Theme.of(context).colorScheme.primary, + width: 4, + ) + : null, + ), child: ClipRRect( borderRadius: Corners.s5Border, child: CircleAvatar( @@ -105,15 +109,16 @@ class UserAvatar extends StatelessWidget { return SizedBox.square( dimension: size, child: DecoratedBox( - decoration: BoxDecoration( - shape: BoxShape.circle, - border: isHovering - ? Border.all( - color: Theme.of(context).colorScheme.primary, - width: 4, - ) - : null, - ), + decoration: decoration ?? + BoxDecoration( + shape: BoxShape.circle, + border: isHovering + ? Border.all( + color: Theme.of(context).colorScheme.primary, + width: 4, + ) + : null, + ), child: ClipRRect( borderRadius: Corners.s5Border, child: CircleAvatar( From 1cecfae6f4c486860cc34c194905c5c7101a859c Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:12:49 +0800 Subject: [PATCH 06/11] chore: fix ui color issue after merge main (#5464) --- .../lib/plugins/ai_chat/presentation/chat_ai_message.dart | 5 ++--- .../lib/plugins/ai_chat/presentation/chat_avatar.dart | 7 +++---- .../lib/plugins/ai_chat/presentation/chat_input.dart | 3 ++- .../plugins/ai_chat/presentation/chat_user_message.dart | 3 ++- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_ai_message.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_ai_message.dart index 5a8e65012d..7a19360490 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_ai_message.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_ai_message.dart @@ -48,9 +48,8 @@ class ChatAIMessageBubble extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - ChatBorderedCircleAvatar( - backgroundColor: Theme.of(context).colorScheme.secondary, - child: const FlowySvg( + const ChatBorderedCircleAvatar( + child: FlowySvg( FlowySvgs.flowy_ai_chat_logo_s, size: Size.square(24), ), diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_avatar.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_avatar.dart index 141432520b..7f2e01f989 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_avatar.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_avatar.dart @@ -24,13 +24,11 @@ class ChatBorderedCircleAvatar extends StatelessWidget { super.key, this.border = const BorderSide(), this.backgroundImage, - this.backgroundColor, this.child, }); final BorderSide border; final ImageProvider? backgroundImage; - final Color? backgroundColor; final Widget? child; @override @@ -41,7 +39,8 @@ class ChatBorderedCircleAvatar extends StatelessWidget { constraints: const BoxConstraints.expand(), child: CircleAvatar( backgroundImage: backgroundImage, - backgroundColor: backgroundColor, + backgroundColor: + Theme.of(context).colorScheme.surfaceContainerHighest, child: child, ), ), @@ -118,7 +117,7 @@ class ChatUserAvatar extends StatelessWidget { shape: BoxShape.circle, border: isHovering ? Border.all( - color: Theme.of(context).colorScheme.primary, + color: Theme.of(context).colorScheme.secondary, width: 4, ) : null, diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart index a981ab9b33..b33c59d640 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_input.dart @@ -269,7 +269,8 @@ class SendButton extends StatelessWidget { Widget build(BuildContext context) { return FlowyIconButton( width: 36, - fillColor: Theme.of(context).colorScheme.secondary, + fillColor: AFThemeExtension.of(context).lightGreyHover, + hoverColor: AFThemeExtension.of(context).lightGreyHover, radius: BorderRadius.circular(18), icon: FlowySvg( FlowySvgs.send_s, diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_message.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_message.dart index f6e55b8090..3e1e4e6c24 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_message.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/presentation/chat_user_message.dart @@ -25,7 +25,8 @@ class ChatUserMessageBubble extends StatelessWidget { @override Widget build(BuildContext context) { const borderRadius = BorderRadius.all(Radius.circular(6)); - final backgroundColor = Theme.of(context).colorScheme.secondary; + final backgroundColor = + Theme.of(context).colorScheme.surfaceContainerHighest; return BlocProvider( create: (context) => ChatUserMessageBloc(message: message), From 890ac5a2139b4e17d369a43fbe7de5b34c92c8cd Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Tue, 4 Jun 2024 20:13:54 +0800 Subject: [PATCH 07/11] chore: chat icon (#5465) --- frontend/appflowy_flutter/lib/plugins/ai_chat/chat.dart | 2 +- .../presentation/home/menu/view/view_add_button.dart | 5 ++++- frontend/resources/flowy_icons/16x/chat_ai_page.svg | 5 +---- frontend/rust-lib/flowy-chat/src/chat.rs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frontend/appflowy_flutter/lib/plugins/ai_chat/chat.dart b/frontend/appflowy_flutter/lib/plugins/ai_chat/chat.dart index cb69ee8d8d..540779b1a1 100644 --- a/frontend/appflowy_flutter/lib/plugins/ai_chat/chat.dart +++ b/frontend/appflowy_flutter/lib/plugins/ai_chat/chat.dart @@ -21,7 +21,7 @@ class AIChatPluginBuilder extends PluginBuilder { } @override - String get menuName => "AIChat"; + String get menuName => "AI Chat"; @override FlowySvgData get icon => FlowySvgs.chat_ai_page_s; diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_add_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_add_button.dart index 3fa23c8f1c..5d01b2a71f 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_add_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_add_button.dart @@ -108,7 +108,10 @@ class ViewAddButtonActionWrapper extends ActionCell { final PluginBuilder pluginBuilder; @override - Widget? leftIcon(Color iconColor) => FlowySvg(pluginBuilder.icon); + Widget? leftIcon(Color iconColor) => FlowySvg( + pluginBuilder.icon, + size: const Size.square(16), + ); @override String get name => pluginBuilder.menuName; diff --git a/frontend/resources/flowy_icons/16x/chat_ai_page.svg b/frontend/resources/flowy_icons/16x/chat_ai_page.svg index e39815f94f..e3585e4ec6 100644 --- a/frontend/resources/flowy_icons/16x/chat_ai_page.svg +++ b/frontend/resources/flowy_icons/16x/chat_ai_page.svg @@ -1,4 +1 @@ - - - - + \ No newline at end of file diff --git a/frontend/rust-lib/flowy-chat/src/chat.rs b/frontend/rust-lib/flowy-chat/src/chat.rs index 712caad91a..70e36df27d 100644 --- a/frontend/rust-lib/flowy-chat/src/chat.rs +++ b/frontend/rust-lib/flowy-chat/src/chat.rs @@ -368,7 +368,7 @@ fn stream_send_chat_messages( messages.push(message); }, Err(err) => { - error!("Failed to send chat message: {}", err); + error!("stream chat message error: {}", err); let pb = ChatMessageErrorPB { chat_id: chat_id.clone(), content: message_content.clone(), From 9f66dcdc8f989a66a6fbaf9438c20682c448063f Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Tue, 4 Jun 2024 22:43:38 +0800 Subject: [PATCH 08/11] chore: bump client api (#5467) --- frontend/appflowy_tauri/src-tauri/Cargo.lock | 52 ++++++++++--------- frontend/appflowy_tauri/src-tauri/Cargo.toml | 16 +++--- frontend/appflowy_web/wasm-libs/Cargo.lock | 46 ++++++++-------- frontend/appflowy_web/wasm-libs/Cargo.toml | 16 +++--- .../appflowy_web_app/src-tauri/Cargo.lock | 38 +++++++------- .../appflowy_web_app/src-tauri/Cargo.toml | 16 +++--- frontend/rust-lib/Cargo.lock | 46 ++++++++-------- frontend/rust-lib/Cargo.toml | 16 +++--- 8 files changed, 127 insertions(+), 119 deletions(-) diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index d02983e577..0c48e8f203 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -162,7 +162,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bincode", @@ -182,7 +182,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bytes", @@ -756,7 +756,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "again", "anyhow", @@ -803,7 +803,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "futures-channel", "futures-util", @@ -877,7 +877,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-trait", @@ -901,7 +901,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-trait", @@ -931,7 +931,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "collab", @@ -950,7 +950,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "bytes", @@ -965,7 +965,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "chrono", @@ -1003,7 +1003,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-stream", @@ -1042,7 +1042,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bincode", @@ -1067,7 +1067,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "async-trait", @@ -1084,7 +1084,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "collab", @@ -1313,7 +1313,7 @@ dependencies = [ "cssparser-macros", "dtoa-short", "itoa 1.0.6", - "phf 0.8.0", + "phf 0.11.2", "smallvec", ] @@ -1424,7 +1424,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", @@ -2832,7 +2832,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "futures-util", @@ -2849,7 +2849,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", @@ -3281,7 +3281,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "reqwest", @@ -4602,18 +4602,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", @@ -4784,7 +4784,7 @@ checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", - "itertools 0.10.5", + "itertools 0.11.0", "log", "multimap", "once_cell", @@ -4805,7 +4805,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.11.0", "proc-macro2", "quote", "syn 2.0.47", @@ -5769,16 +5769,18 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", "appflowy-ai-client", + "bytes", "chrono", "collab-entity", "database-entity", "futures", "gotrue-entity", + "pin-project", "reqwest", "serde", "serde_json", diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.toml b/frontend/appflowy_tauri/src-tauri/Cargo.toml index 9cfcf94740..5f9b079392 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.toml +++ b/frontend/appflowy_tauri/src-tauri/Cargo.toml @@ -52,7 +52,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "b36715dc2427e23a15fa81c629e1817d3dbf1e1a" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "3f55cea9ca386875a1668ef30600c83cd6a1ffe2" } [dependencies] serde_json.workspace = true @@ -106,10 +106,10 @@ default = ["custom-protocol"] custom-protocol = ["tauri/custom-protocol"] [patch.crates-io] -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } \ No newline at end of file +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } \ No newline at end of file diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index 0ed8840871..b8da195c3d 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -216,7 +216,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bincode", @@ -236,7 +236,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bytes", @@ -562,7 +562,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "again", "anyhow", @@ -609,7 +609,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "futures-channel", "futures-util", @@ -653,7 +653,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-trait", @@ -677,7 +677,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "collab", @@ -696,7 +696,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "bytes", @@ -711,7 +711,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "chrono", @@ -749,7 +749,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-stream", @@ -787,7 +787,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bincode", @@ -812,7 +812,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "async-trait", @@ -829,7 +829,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "collab", @@ -1026,7 +1026,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", @@ -1815,7 +1815,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "futures-util", @@ -1832,7 +1832,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", @@ -2133,7 +2133,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "reqwest", @@ -2947,18 +2947,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", @@ -3773,16 +3773,18 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", "appflowy-ai-client", + "bytes", "chrono", "collab-entity", "database-entity", "futures", "gotrue-entity", + "pin-project", "reqwest", "serde", "serde_json", @@ -5039,4 +5041,4 @@ dependencies = [ [[patch.unused]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" diff --git a/frontend/appflowy_web/wasm-libs/Cargo.toml b/frontend/appflowy_web/wasm-libs/Cargo.toml index 01fc3fad33..225c339b1c 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.toml +++ b/frontend/appflowy_web/wasm-libs/Cargo.toml @@ -55,7 +55,7 @@ yrs = "0.18.8" # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "b36715dc2427e23a15fa81c629e1817d3dbf1e1a" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "3f55cea9ca386875a1668ef30600c83cd6a1ffe2" } @@ -70,10 +70,10 @@ opt-level = 3 codegen-units = 1 [patch.crates-io] -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } \ No newline at end of file +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } \ No newline at end of file diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock index 23252b551c..d7aaa79525 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.lock +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -153,7 +153,7 @@ checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bincode", @@ -173,7 +173,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bytes", @@ -730,7 +730,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "again", "anyhow", @@ -777,7 +777,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "futures-channel", "futures-util", @@ -860,7 +860,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-trait", @@ -884,7 +884,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-trait", @@ -914,7 +914,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "collab", @@ -933,7 +933,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "bytes", @@ -948,7 +948,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "chrono", @@ -986,7 +986,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-stream", @@ -1025,7 +1025,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bincode", @@ -1050,7 +1050,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "async-trait", @@ -1067,7 +1067,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "collab", @@ -1411,7 +1411,7 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", @@ -2906,7 +2906,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "futures-util", @@ -2923,7 +2923,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", @@ -3360,7 +3360,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "reqwest", @@ -5864,16 +5864,18 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", "appflowy-ai-client", + "bytes", "chrono", "collab-entity", "database-entity", "futures", "gotrue-entity", + "pin-project", "reqwest", "serde", "serde_json", diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.toml b/frontend/appflowy_web_app/src-tauri/Cargo.toml index 9db2fea415..21df3b1bbc 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.toml +++ b/frontend/appflowy_web_app/src-tauri/Cargo.toml @@ -52,7 +52,7 @@ collab-user = { version = "0.2" } # Run the script: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "b36715dc2427e23a15fa81c629e1817d3dbf1e1a" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "3f55cea9ca386875a1668ef30600c83cd6a1ffe2" } [dependencies] serde_json.workspace = true @@ -107,10 +107,10 @@ default = ["custom-protocol"] custom-protocol = ["tauri/custom-protocol"] [patch.crates-io] -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } \ No newline at end of file +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } \ No newline at end of file diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index 9a48c6db27..b98f682a2c 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -163,7 +163,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "app-error" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bincode", @@ -183,7 +183,7 @@ dependencies = [ [[package]] name = "appflowy-ai-client" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bytes", @@ -664,7 +664,7 @@ dependencies = [ [[package]] name = "client-api" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "again", "anyhow", @@ -711,7 +711,7 @@ dependencies = [ [[package]] name = "client-websocket" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "futures-channel", "futures-util", @@ -754,7 +754,7 @@ dependencies = [ [[package]] name = "collab" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-trait", @@ -778,7 +778,7 @@ dependencies = [ [[package]] name = "collab-database" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-trait", @@ -808,7 +808,7 @@ dependencies = [ [[package]] name = "collab-document" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "collab", @@ -827,7 +827,7 @@ dependencies = [ [[package]] name = "collab-entity" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "bytes", @@ -842,7 +842,7 @@ dependencies = [ [[package]] name = "collab-folder" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "chrono", @@ -880,7 +880,7 @@ dependencies = [ [[package]] name = "collab-plugins" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "async-stream", @@ -919,7 +919,7 @@ dependencies = [ [[package]] name = "collab-rt-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "bincode", @@ -944,7 +944,7 @@ dependencies = [ [[package]] name = "collab-rt-protocol" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "async-trait", @@ -961,7 +961,7 @@ dependencies = [ [[package]] name = "collab-user" version = "0.2.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=cca5135f0010fa5de22a298cbed939e21575538c#cca5135f0010fa5de22a298cbed939e21575538c" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=6febf0397e66ebf0a281980a2e7602d7af00c975#6febf0397e66ebf0a281980a2e7602d7af00c975" dependencies = [ "anyhow", "collab", @@ -1264,7 +1264,7 @@ checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" [[package]] name = "database-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", @@ -2518,7 +2518,7 @@ dependencies = [ [[package]] name = "gotrue" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "futures-util", @@ -2535,7 +2535,7 @@ dependencies = [ [[package]] name = "gotrue-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", @@ -2900,7 +2900,7 @@ dependencies = [ [[package]] name = "infra" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "reqwest", @@ -3891,18 +3891,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", @@ -4983,16 +4983,18 @@ dependencies = [ [[package]] name = "shared-entity" version = "0.1.0" -source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=b36715dc2427e23a15fa81c629e1817d3dbf1e1a#b36715dc2427e23a15fa81c629e1817d3dbf1e1a" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Cloud?rev=3f55cea9ca386875a1668ef30600c83cd6a1ffe2#3f55cea9ca386875a1668ef30600c83cd6a1ffe2" dependencies = [ "anyhow", "app-error", "appflowy-ai-client", + "bytes", "chrono", "collab-entity", "database-entity", "futures", "gotrue-entity", + "pin-project", "reqwest", "serde", "serde_json", diff --git a/frontend/rust-lib/Cargo.toml b/frontend/rust-lib/Cargo.toml index c793b3ec46..966240ac22 100644 --- a/frontend/rust-lib/Cargo.toml +++ b/frontend/rust-lib/Cargo.toml @@ -93,7 +93,7 @@ yrs = "0.18.8" # Run the script.add_workspace_members: # scripts/tool/update_client_api_rev.sh new_rev_id # ⚠️⚠️⚠️️ -client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "b36715dc2427e23a15fa81c629e1817d3dbf1e1a" } +client-api = { git = "https://github.com/AppFlowy-IO/AppFlowy-Cloud", rev = "3f55cea9ca386875a1668ef30600c83cd6a1ffe2" } [profile.dev] opt-level = 1 @@ -132,10 +132,10 @@ rocksdb = { git = "https://github.com/LucasXu0/rust-rocksdb", rev = "21cf4a23ec1 # To switch to the local path, run: # scripts/tool/update_collab_source.sh # ⚠️⚠️⚠️️ -collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } -collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "cca5135f0010fa5de22a298cbed939e21575538c" } +collab = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-entity = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-folder = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-document = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-database = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-plugins = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } +collab-user = { version = "0.2", git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "6febf0397e66ebf0a281980a2e7602d7af00c975" } From e4eff7e63241d17dfaa83c665f0636e961104eac Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Wed, 5 Jun 2024 09:18:43 +0800 Subject: [PATCH 09/11] feat: support slide actions on mobile (#5463) * feat: support slide actions on mobile * fix: some ui issues * fix: scale down emoji size on windows * fix: flutter analyze * fix: force text height on macos --- frontend/appflowy_flutter/ios/Podfile.lock | 4 +- .../bottom_sheet_add_new_page.dart | 5 + .../bottom_sheet_view_item_body.dart | 14 +- .../default_mobile_action_pane.dart | 157 ++++++++++++++---- .../mobile_home_favorite_folder.dart | 16 +- .../presentation/home/mobile_folders.dart | 2 +- .../home/mobile_home_page_header.dart | 38 ++--- .../home/recent_folder/recent_space.dart | 55 +++--- .../mobile_home_section_folder.dart | 15 ++ .../mobile_home_section_folder_header.dart | 2 +- .../home/shared/mobile_view_card.dart | 41 +++-- .../workspace_menu_bottom_sheet.dart | 40 ++++- .../page_item/mobile_slide_action_button.dart | 4 + .../page_item/mobile_view_item.dart | 96 ----------- .../sidebar/favorites/favorite_folder.dart | 6 +- .../menu/sidebar/header/sidebar_top_menu.dart | 2 +- .../home/menu/sidebar/sidebar.dart | 25 ++- .../workspace/_sidebar_workspace_icon.dart | 6 +- .../sidebar/workspace/sidebar_workspace.dart | 2 +- .../home/menu/view/view_item.dart | 3 - .../flowy_infra_ui/lib/style_widget/text.dart | 24 ++- .../lib/widget/flowy_tooltip.dart | 1 + 22 files changed, 323 insertions(+), 235 deletions(-) diff --git a/frontend/appflowy_flutter/ios/Podfile.lock b/frontend/appflowy_flutter/ios/Podfile.lock index 6f75b60ade..5a2d069c36 100644 --- a/frontend/appflowy_flutter/ios/Podfile.lock +++ b/frontend/appflowy_flutter/ios/Podfile.lock @@ -200,7 +200,7 @@ SPEC CHECKSUMS: file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 flowy_infra_ui: 0455e1fa8c51885aa1437848e361e99419f34ebc Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - fluttertoast: fafc4fa4d01a6a9e4f772ecd190ffa525e9e2d9c + fluttertoast: 31b00dabfa7fb7bacd9e7dbee580d7a2ff4bf265 image_gallery_saver: cb43cc43141711190510e92c460eb1655cd343cb image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425 integration_test: ce0a3ffa1de96d1a89ca0ac26fca7ea18a749ef4 @@ -227,4 +227,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: d0d9b4ff572d8695c38eb3f9b490f55cdfc57eca -COCOAPODS: 1.11.3 +COCOAPODS: 1.15.2 diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart index 9bd6f22880..bc8706f8b8 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_add_new_page.dart @@ -21,6 +21,7 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { children: [ FlowyOptionTile.text( text: LocaleKeys.document_menuName.tr(), + height: 52.0, leftIcon: const FlowySvg( FlowySvgs.document_s, size: Size.square(18), @@ -30,6 +31,7 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { ), FlowyOptionTile.text( text: LocaleKeys.grid_menuName.tr(), + height: 52.0, leftIcon: const FlowySvg( FlowySvgs.grid_s, size: Size.square(18), @@ -39,6 +41,7 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { ), FlowyOptionTile.text( text: LocaleKeys.board_menuName.tr(), + height: 52.0, leftIcon: const FlowySvg( FlowySvgs.board_s, size: Size.square(18), @@ -48,6 +51,7 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { ), FlowyOptionTile.text( text: LocaleKeys.calendar_menuName.tr(), + height: 52.0, leftIcon: const FlowySvg( FlowySvgs.calendar_s, size: Size.square(18), @@ -57,6 +61,7 @@ class AddNewPageWidgetBottomSheet extends StatelessWidget { ), FlowyOptionTile.text( text: LocaleKeys.chat_newChat.tr(), + height: 52.0, leftIcon: const FlowySvg( FlowySvgs.chat_ai_page_s, size: Size.square(18), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart index d9c6382288..a078521aec 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/bottom_sheet_view_item_body.dart @@ -44,6 +44,7 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { case MobileViewItemBottomSheetBodyAction.rename: return FlowyOptionTile.text( text: LocaleKeys.button_rename.tr(), + height: 52.0, leftIcon: const FlowySvg( FlowySvgs.view_item_rename_s, size: Size.square(18), @@ -57,6 +58,7 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { case MobileViewItemBottomSheetBodyAction.duplicate: return FlowyOptionTile.text( text: LocaleKeys.button_duplicate.tr(), + height: 52.0, leftIcon: const FlowySvg( FlowySvgs.duplicate_s, size: Size.square(18), @@ -71,6 +73,7 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { case MobileViewItemBottomSheetBodyAction.share: return FlowyOptionTile.text( text: LocaleKeys.button_share.tr(), + height: 52.0, leftIcon: const FlowySvg( FlowySvgs.share_s, size: Size.square(18), @@ -84,9 +87,10 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { case MobileViewItemBottomSheetBodyAction.delete: return FlowyOptionTile.text( text: LocaleKeys.button_delete.tr(), + height: 52.0, textColor: Theme.of(context).colorScheme.error, leftIcon: FlowySvg( - FlowySvgs.delete_s, + FlowySvgs.trash_s, size: const Size.square(18), color: Theme.of(context).colorScheme.error, ), @@ -98,6 +102,7 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { ); case MobileViewItemBottomSheetBodyAction.addToFavorites: return FlowyOptionTile.text( + height: 52.0, text: LocaleKeys.button_addToFavorites.tr(), leftIcon: const FlowySvg( FlowySvgs.favorite_s, @@ -111,6 +116,7 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { ); case MobileViewItemBottomSheetBodyAction.removeFromFavorites: return FlowyOptionTile.text( + height: 52.0, text: LocaleKeys.button_removeFromFavorites.tr(), leftIcon: const FlowySvg( FlowySvgs.favorite_section_remove_from_favorite_s, @@ -124,6 +130,7 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { ); case MobileViewItemBottomSheetBodyAction.removeFromRecent: return FlowyOptionTile.text( + height: 52.0, text: LocaleKeys.button_removeFromRecent.tr(), leftIcon: const FlowySvg( FlowySvgs.remove_from_recent_s, @@ -137,7 +144,10 @@ class MobileViewItemBottomSheetBody extends StatelessWidget { ); case MobileViewItemBottomSheetBodyAction.divider: - return const Divider(height: 0.5); + return const Padding( + padding: EdgeInsets.symmetric(horizontal: 12.0), + child: Divider(height: 0.5), + ); } } } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart index 17ca604717..022d0c224c 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart @@ -1,10 +1,15 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; +import 'package:appflowy/mobile/presentation/home/shared/mobile_view_card.dart'; import 'package:appflowy/mobile/presentation/page_item/mobile_slide_action_button.dart'; import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; +import 'package:appflowy/workspace/application/recent/recent_views_bloc.dart'; +import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:flowy_infra/theme_extension.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; @@ -13,11 +18,14 @@ enum MobilePaneActionType { delete, addToFavorites, removeFromFavorites, - more; + more, + add; MobileSlideActionButton actionButton( - BuildContext context, - ) { + BuildContext context, { + MobileViewCardType? cardType, + FolderSpaceType? spaceType, + }) { switch (this) { case MobilePaneActionType.delete: return MobileSlideActionButton( @@ -29,59 +37,88 @@ enum MobilePaneActionType { ); case MobilePaneActionType.removeFromFavorites: return MobileSlideActionButton( - backgroundColor: Colors.orange, - svg: FlowySvgs.favorite_s, + backgroundColor: const Color(0xFFFA217F), + svg: FlowySvgs.favorite_section_remove_from_favorite_s, + size: 24.0, onPressed: (context) => context .read() .add(FavoriteEvent.toggle(context.read().view)), ); case MobilePaneActionType.addToFavorites: return MobileSlideActionButton( - backgroundColor: Colors.orange, - svg: FlowySvgs.m_favorite_unselected_lg, - size: 34.0, + backgroundColor: const Color(0xFF00C8FF), + svg: FlowySvgs.favorite_s, + size: 24.0, onPressed: (context) => context .read() .add(FavoriteEvent.toggle(context.read().view)), ); - case MobilePaneActionType.more: + case MobilePaneActionType.add: return MobileSlideActionButton( - backgroundColor: Colors.grey, - svg: FlowySvgs.three_dots_vertical_s, + backgroundColor: const Color(0xFF00C8FF), + svg: FlowySvgs.add_m, size: 28.0, + onPressed: (context) { + final viewBloc = context.read(); + final view = viewBloc.state.view; + final title = view.name; + showMobileBottomSheet( + context, + showHeader: true, + title: title, + showDragHandle: true, + showCloseButton: true, + useRootNavigator: true, + backgroundColor: Theme.of(context).colorScheme.surface, + builder: (sheetContext) { + return AddNewPageWidgetBottomSheet( + view: view, + onAction: (layout) { + context.read().add( + ViewEvent.createView( + LocaleKeys.menuAppHeader_defaultNewPageName.tr(), + layout, + section: spaceType!.toViewSectionPB, + ), + ); + }, + ); + }, + ); + }, + ); + case MobilePaneActionType.more: + return MobileSlideActionButton( + backgroundColor: const Color(0xE5515563), + svg: FlowySvgs.three_dots_s, + size: 24.0, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(10), + bottomLeft: Radius.circular(10), + ), onPressed: (context) { final viewBloc = context.read(); final favoriteBloc = context.read(); + final recentViewsBloc = context.read(); showMobileBottomSheet( context, showDragHandle: true, showDivider: false, - backgroundColor: AFThemeExtension.of(context).background, useRootNavigator: true, + backgroundColor: Theme.of(context).colorScheme.surface, builder: (context) { return MultiBlocProvider( providers: [ BlocProvider.value(value: viewBloc), BlocProvider.value(value: favoriteBloc), + if (recentViewsBloc != null) + BlocProvider.value(value: recentViewsBloc), ], child: BlocBuilder( builder: (context, state) { - final isFavorite = state.view.isFavorite; return MobileViewItemBottomSheet( view: viewBloc.state.view, - actions: [ - isFavorite - ? MobileViewItemBottomSheetBodyAction - .removeFromFavorites - : MobileViewItemBottomSheetBodyAction - .addToFavorites, - MobileViewItemBottomSheetBodyAction.divider, - MobileViewItemBottomSheetBodyAction.rename, - if (state.view.layout != ViewLayoutPB.Chat) - MobileViewItemBottomSheetBodyAction.duplicate, - MobileViewItemBottomSheetBodyAction.divider, - MobileViewItemBottomSheetBodyAction.delete, - ], + actions: _buildActions(state.view, cardType: cardType), ); }, ), @@ -92,19 +129,71 @@ enum MobilePaneActionType { ); } } + + List _buildActions( + ViewPB view, { + MobileViewCardType? cardType, + }) { + final isFavorite = view.isFavorite; + + if (cardType != null) { + switch (cardType) { + case MobileViewCardType.recent: + return [ + isFavorite + ? MobileViewItemBottomSheetBodyAction.removeFromFavorites + : MobileViewItemBottomSheetBodyAction.addToFavorites, + MobileViewItemBottomSheetBodyAction.divider, + if (view.layout != ViewLayoutPB.Chat) + MobileViewItemBottomSheetBodyAction.duplicate, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.removeFromRecent, + ]; + case MobileViewCardType.favorite: + return [ + isFavorite + ? MobileViewItemBottomSheetBodyAction.removeFromFavorites + : MobileViewItemBottomSheetBodyAction.addToFavorites, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.duplicate, + ]; + } + } + + return [ + isFavorite + ? MobileViewItemBottomSheetBodyAction.removeFromFavorites + : MobileViewItemBottomSheetBodyAction.addToFavorites, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.rename, + if (view.layout != ViewLayoutPB.Chat) + MobileViewItemBottomSheetBodyAction.duplicate, + MobileViewItemBottomSheetBodyAction.divider, + MobileViewItemBottomSheetBodyAction.delete, + ]; + } } ActionPane buildEndActionPane( BuildContext context, - List actions, -) { + List actions, { + bool needSpace = true, + MobileViewCardType? cardType, + FolderSpaceType? spaceType, +}) { + debugPrint('actions: $actions'); return ActionPane( motion: const ScrollMotion(), extentRatio: actions.length / 5, - children: actions - .map( - (action) => action.actionButton(context), - ) - .toList(), + children: [ + if (needSpace) const HSpace(20), + ...actions.map( + (action) => action.actionButton( + context, + spaceType: spaceType, + cardType: cardType, + ), + ), + ], ); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart index d683cf3507..57ac43f255 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/favorite_folder/mobile_home_favorite_folder.dart @@ -63,12 +63,16 @@ class MobileFavoriteFolder extends StatelessWidget { view: view, level: 0, onSelected: context.pushView, - endActionPane: (context) => buildEndActionPane(context, [ - view.isFavorite - ? MobilePaneActionType.removeFromFavorites - : MobilePaneActionType.addToFavorites, - MobilePaneActionType.more, - ]), + endActionPane: (context) => buildEndActionPane( + context, + [ + view.isFavorite + ? MobilePaneActionType.removeFromFavorites + : MobilePaneActionType.addToFavorites, + MobilePaneActionType.more, + ], + spaceType: FolderSpaceType.favorite, + ), ), ), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart index 100649701d..78be82ec99 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_folders.dart @@ -111,7 +111,7 @@ class _TrashButton extends StatelessWidget { height: 52, child: FlowyButton( expand: true, - margin: const EdgeInsets.symmetric(vertical: 8), + margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 2.0), leftIcon: const FlowySvg( FlowySvgs.m_delete_s, ), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart index 5ae2ff1430..28d0915aef 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page_header.dart @@ -123,12 +123,13 @@ class _MobileWorkspace extends StatelessWidget { child: Row( children: [ SizedBox.square( - dimension: 34.0, + dimension: currentWorkspace.icon.isNotEmpty ? 34.0 : 26.0, child: WorkspaceIcon( workspace: currentWorkspace, iconSize: 26, fontSize: 16.0, enableEdit: false, + alignment: Alignment.centerLeft, onSelected: (result) => context.read().add( UserWorkspaceEvent.updateWorkspaceIcon( currentWorkspace.workspaceId, @@ -137,32 +138,13 @@ class _MobileWorkspace extends StatelessWidget { ), ), ), - const HSpace(8), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - FlowyText.semibold( - currentWorkspace.name, - fontSize: 16.0, - overflow: TextOverflow.ellipsis, - ), - const HSpace(4.0), - const FlowySvg(FlowySvgs.list_dropdown_s), - ], - ), - FlowyText.regular( - userProfile.email.isNotEmpty - ? userProfile.email - : userProfile.name, - overflow: TextOverflow.ellipsis, - fontSize: 12, - color: Theme.of(context).colorScheme.onSurface, - ), - ], - ), + currentWorkspace.icon.isNotEmpty + ? const HSpace(2) + : const HSpace(8), + FlowyText.semibold( + currentWorkspace.name, + fontSize: 16.0, + overflow: TextOverflow.ellipsis, ), ], ), @@ -179,7 +161,9 @@ class _MobileWorkspace extends StatelessWidget { showDivider: false, showHeader: true, showDragHandle: true, + showCloseButton: true, title: LocaleKeys.workspace_menuTitle.tr(), + backgroundColor: Theme.of(context).colorScheme.surface, builder: (_) { return BlocProvider.value( value: context.read(), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart index 3cab831c23..3523d75720 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/recent_folder/recent_space.dart @@ -6,6 +6,7 @@ import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_slidable/flutter_slidable.dart'; class MobileRecentSpace extends StatefulWidget { const MobileRecentSpace({super.key}); @@ -62,34 +63,36 @@ class _RecentViews extends StatelessWidget { @override Widget build(BuildContext context) { - return Scrollbar( - child: ListView.separated( - key: const PageStorageKey('recent_views_page_storage_key'), - padding: const EdgeInsets.symmetric( - horizontal: HomeSpaceViewSizes.mHorizontalPadding, - ), - itemBuilder: (context, index) { - final sectionView = recentViews[index]; - return Container( - padding: const EdgeInsets.symmetric(vertical: 24.0), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Theme.of(context).dividerColor, - width: 0.5, + return SlidableAutoCloseBehavior( + child: Scrollbar( + child: ListView.separated( + key: const PageStorageKey('recent_views_page_storage_key'), + padding: const EdgeInsets.symmetric( + horizontal: HomeSpaceViewSizes.mHorizontalPadding, + ), + itemBuilder: (context, index) { + final sectionView = recentViews[index]; + return Container( + padding: const EdgeInsets.symmetric(vertical: 24.0), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Theme.of(context).dividerColor, + width: 0.5, + ), ), ), - ), - child: MobileViewCard( - key: ValueKey(sectionView.item.id), - view: sectionView.item, - timestamp: sectionView.timestamp, - type: MobileViewCardType.recent, - ), - ); - }, - separatorBuilder: (context, index) => const HSpace(8), - itemCount: recentViews.length, + child: MobileViewCard( + key: ValueKey(sectionView.item.id), + view: sectionView.item, + timestamp: sectionView.timestamp, + type: MobileViewCardType.recent, + ), + ); + }, + separatorBuilder: (context, index) => const HSpace(8), + itemCount: recentViews.length, + ), ), ); } diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart index 7a14a4d48d..4cd212f5a9 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder.dart @@ -1,9 +1,11 @@ import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; +import 'package:appflowy/mobile/presentation/bottom_sheet/default_mobile_action_pane.dart'; import 'package:appflowy/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart'; import 'package:appflowy/mobile/presentation/page_item/mobile_view_item.dart'; import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; +import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -69,6 +71,19 @@ class MobileSectionFolder extends StatelessWidget { leftPadding: HomeSpaceViewSizes.leftPadding, isFeedback: false, onSelected: context.pushView, + endActionPane: (context) { + final view = context.read().state.view; + return buildEndActionPane( + context, + [ + MobilePaneActionType.more, + if (view.layout == ViewLayoutPB.Document) + MobilePaneActionType.add, + ], + spaceType: spaceType, + needSpace: false, + ); + }, ), ), ], diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart index 49a9829d8a..aa84dc7601 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/section_folder/mobile_home_section_folder_header.dart @@ -38,7 +38,7 @@ class _MobileSectionFolderHeaderState extends State { widget.title, fontSize: 16.0, ), - margin: const EdgeInsets.symmetric(vertical: 8), + margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 2.0), expandText: false, iconPadding: 2, mainAxisAlignment: MainAxisAlignment.start, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart index 78f03569be..b995236279 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/shared/mobile_view_card.dart @@ -22,6 +22,7 @@ import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:provider/provider.dart'; import 'package:string_validator/string_validator.dart'; @@ -63,21 +64,33 @@ class MobileViewCard extends StatelessWidget { ], child: BlocBuilder( builder: (context, state) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTapUp: (_) => context.pushView(view), - onLongPressUp: () => _showActionSheet(context), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Expanded(child: _buildDescription(context, state)), - const HSpace(20.0), - SizedBox( - width: 84, - height: 60, - child: _buildCover(context, state), - ), + return Slidable( + endActionPane: buildEndActionPane( + context, + [ + MobilePaneActionType.more, + context.watch().state.view.isFavorite + ? MobilePaneActionType.removeFromFavorites + : MobilePaneActionType.addToFavorites, ], + cardType: type, + ), + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTapUp: (_) => context.pushView(view), + onLongPressUp: () => _showActionSheet(context), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded(child: _buildDescription(context, state)), + const HSpace(20.0), + SizedBox( + width: 84, + height: 60, + child: _buildCover(context, state), + ), + ], + ), ), ); }, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart index 496c5607a5..17962bcc3c 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/workspaces/workspace_menu_bottom_sheet.dart @@ -1,6 +1,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/widgets/widgets.dart'; +import 'package:appflowy/util/theme_extension.dart'; import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart'; import 'package:appflowy/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/members/workspace_member_bloc.dart'; @@ -27,7 +28,13 @@ class MobileWorkspaceMenu extends StatelessWidget { @override Widget build(BuildContext context) { - final List children = []; + final List children = [ + _WorkspaceUserItem(userProfile: userProfile), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 10), + child: Divider(height: 0.5), + ), + ]; for (var i = 0; i < workspaces.length; i++) { final workspace = workspaces[i]; children.add( @@ -35,7 +42,7 @@ class MobileWorkspaceMenu extends StatelessWidget { key: ValueKey(workspace.workspaceId), userProfile: userProfile, workspace: workspace, - showTopBorder: i == 0, + showTopBorder: false, currentWorkspace: currentWorkspace, onWorkspaceSelected: onWorkspaceSelected, ), @@ -47,6 +54,34 @@ class MobileWorkspaceMenu extends StatelessWidget { } } +class _WorkspaceUserItem extends StatelessWidget { + const _WorkspaceUserItem({required this.userProfile}); + + final UserProfilePB userProfile; + + @override + Widget build(BuildContext context) { + final color = Theme.of(context).isLightMode + ? const Color(0x99333333) + : const Color(0x99CCCCCC); + return FlowyOptionTile.text( + height: 32, + showTopBorder: false, + showBottomBorder: false, + content: Expanded( + child: Padding( + padding: const EdgeInsets.only(), + child: FlowyText( + userProfile.email, + fontSize: 14, + color: color, + ), + ), + ), + ); + } +} + class _WorkspaceMenuItem extends StatelessWidget { const _WorkspaceMenuItem({ super.key, @@ -102,6 +137,7 @@ class _WorkspaceMenuItem extends StatelessWidget { ), height: 60, showTopBorder: showTopBorder, + showBottomBorder: false, leftIcon: WorkspaceIcon( enableEdit: false, iconSize: 26, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_slide_action_button.dart b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_slide_action_button.dart index 5aebb53100..b3d021613e 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_slide_action_button.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_slide_action_button.dart @@ -9,6 +9,7 @@ class MobileSlideActionButton extends StatelessWidget { required this.svg, this.size = 32.0, this.backgroundColor = Colors.transparent, + this.borderRadius = BorderRadius.zero, required this.onPressed, }); @@ -16,15 +17,18 @@ class MobileSlideActionButton extends StatelessWidget { final double size; final Color backgroundColor; final SlidableActionCallback onPressed; + final BorderRadius borderRadius; @override Widget build(BuildContext context) { return CustomSlidableAction( + borderRadius: borderRadius, backgroundColor: backgroundColor, onPressed: (context) { HapticFeedback.mediumImpact(); onPressed(context); }, + padding: EdgeInsets.zero, child: FlowySvg( svg, size: Size.square(size), diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart index 4b4672f6a7..2d20581b98 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/page_item/mobile_view_item.dart @@ -1,16 +1,11 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; -import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/application/mobile_router.dart'; -import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; -import 'package:appflowy/mobile/presentation/page_item/mobile_view_item_add_button.dart'; -import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart'; import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart'; import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/presentation/home/home_sizes.dart'; import 'package:appflowy/workspace/presentation/home/menu/view/draggable_view_item.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; -import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -270,17 +265,6 @@ class _SingleMobileInnerViewItemState extends State { ), ]; - // hover action - - // ··· more action button - children.add(_buildViewMoreButton(context)); - // only support add button for document layout - if (!widget.isFeedback && widget.view.layout == ViewLayoutPB.Document) { - // + button - - children.add(_buildViewAddButton(context)); - } - Widget child = InkWell( borderRadius: BorderRadius.circular(4.0), onTap: () => widget.onSelected(widget.view), @@ -345,86 +329,6 @@ class _SingleMobileInnerViewItemState extends State { }, ); } - - // + button - Widget _buildViewAddButton(BuildContext context) { - return MobileViewAddButton( - onPressed: () { - final title = widget.view.name; - showMobileBottomSheet( - context, - showHeader: true, - title: title, - showDragHandle: true, - showCloseButton: true, - useRootNavigator: true, - builder: (sheetContext) { - return AddNewPageWidgetBottomSheet( - view: widget.view, - onAction: (layout) { - Navigator.of(sheetContext).pop(); - context.read().add( - ViewEvent.createView( - LocaleKeys.menuAppHeader_defaultNewPageName.tr(), - layout, - section: widget.spaceType != FolderSpaceType.favorite - ? widget.spaceType.toViewSectionPB - : null, - ), - ); - }, - ); - }, - ); - }, - ); - } - - // + button - Widget _buildViewMoreButton(BuildContext context) { - return MobileViewMoreButton(onPressed: () => _showMoreActions(context)); - } - - Future _showMoreActions(BuildContext context) async { - final viewBloc = context.read(); - final favoriteBloc = context.read(); - await showMobileBottomSheet( - context, - showHeader: true, - title: widget.view.name, - showDragHandle: true, - showCloseButton: true, - useRootNavigator: true, - builder: (context) { - return MultiBlocProvider( - providers: [ - BlocProvider.value(value: viewBloc), - BlocProvider.value(value: favoriteBloc), - ], - child: BlocBuilder( - builder: (context, state) { - final isFavorite = state.view.isFavorite; - return MobileViewItemBottomSheet( - view: viewBloc.state.view, - actions: [ - isFavorite - ? MobileViewItemBottomSheetBodyAction.removeFromFavorites - : MobileViewItemBottomSheetBodyAction.addToFavorites, - MobileViewItemBottomSheetBodyAction.divider, - MobileViewItemBottomSheetBodyAction.rename, - MobileViewItemBottomSheetBodyAction.divider, - if (state.view.layout != ViewLayoutPB.Chat) - MobileViewItemBottomSheetBodyAction.duplicate, - MobileViewItemBottomSheetBodyAction.divider, - MobileViewItemBottomSheetBodyAction.delete, - ], - ); - }, - ), - ); - }, - ); - } } // workaround: we should use view.isEndPoint or something to check if the view can contain child views. But currently, we don't have that field. diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart index a3cb50fd06..f73fa04cd0 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/favorites/favorite_folder.dart @@ -189,11 +189,13 @@ class FavoriteMoreButton extends StatelessWidget { margin: EdgeInsets.zero, child: FlowyButton( onTap: () {}, - margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 7.0), + margin: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 7.0), leftIcon: const FlowySvg( FlowySvgs.workspace_three_dots_s, ), - text: FlowyText.regular(LocaleKeys.button_more.tr()), + text: FlowyText.regular( + LocaleKeys.button_more.tr(), + ), ), ); } diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart index 240a660966..67bcbc782f 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/header/sidebar_top_menu.dart @@ -88,7 +88,7 @@ class SidebarTopMenu extends StatelessWidget { builder: (_, value, ___) => Opacity( opacity: value ? 1 : 0, child: Padding( - padding: const EdgeInsets.only(top: 12.0, right: 4.0), + padding: const EdgeInsets.only(top: 12.0, right: 6.0), child: FlowyTooltip( richMessage: textSpan, child: Listener( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index c7d8e3fbc2..6956bc51d6 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -191,6 +191,7 @@ class _SidebarState extends State<_Sidebar> { Timer? _scrollDebounce; bool _isScrolling = false; final _isHovered = ValueNotifier(false); + final _scrollOffset = ValueNotifier(0); @override void initState() { @@ -203,6 +204,7 @@ class _SidebarState extends State<_Sidebar> { _scrollDebounce?.cancel(); _scrollController.removeListener(_onScrollChanged); _scrollController.dispose(); + _scrollOffset.dispose(); _isHovered.dispose(); super.dispose(); } @@ -255,11 +257,20 @@ class _SidebarState extends State<_Sidebar> { const SidebarNewPageButton(), // scrollable document list const VSpace(12.0), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 12.0), - child: Divider( - color: Color(0x1E1F2329), - height: 0.5, + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: ValueListenableBuilder( + valueListenable: _scrollOffset, + builder: (_, offset, child) { + return Opacity( + opacity: offset > 0 ? 1 : 0, + child: child, + ); + }, + child: const Divider( + color: Color(0x141F2329), + height: 0.5, + ), ), ), Expanded( @@ -281,7 +292,7 @@ class _SidebarState extends State<_Sidebar> { Padding( padding: menuHorizontalInset + const EdgeInsets.symmetric(horizontal: 4.0), - child: const Divider(height: 1.0, color: Color(0x141F2329)), + child: const Divider(height: 0.5, color: Color(0x141F2329)), ), const VSpace(8), Padding( @@ -302,6 +313,8 @@ class _SidebarState extends State<_Sidebar> { _scrollDebounce?.cancel(); _scrollDebounce = Timer(const Duration(milliseconds: 300), _setScrollStopped); + + _scrollOffset.value = _scrollController.offset; } void _setScrollStopped() { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart index 6f96e6abc2..c05cf1e148 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/_sidebar_workspace_icon.dart @@ -17,6 +17,7 @@ class WorkspaceIcon extends StatefulWidget { required this.onSelected, this.borderRadius = 4, this.emojiSize, + this.alignment, }); final UserWorkspacePB workspace; @@ -26,6 +27,7 @@ class WorkspaceIcon extends StatefulWidget { final double? emojiSize; final void Function(EmojiPickerResult) onSelected; final double borderRadius; + final Alignment? alignment; @override State createState() => _WorkspaceIconState(); @@ -38,8 +40,8 @@ class _WorkspaceIconState extends State { Widget build(BuildContext context) { Widget child = widget.workspace.icon.isNotEmpty ? Container( - width: widget.iconSize, - alignment: Alignment.center, + width: widget.emojiSize ?? widget.iconSize, + alignment: widget.alignment ?? Alignment.center, child: FlowyText.emoji( widget.workspace.icon, fontSize: widget.emojiSize ?? widget.iconSize, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart index 1dddce8ac6..2fa91a8da1 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/workspace/sidebar_workspace.dart @@ -50,7 +50,7 @@ class _SidebarWorkspaceState extends State { UserSettingButton(userProfile: widget.userProfile), const HSpace(8.0), const NotificationButton(), - const HSpace(10.0), + const HSpace(12.0), ], ); }, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart index cdbbd76e33..6b74be1e4f 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/view/view_item.dart @@ -434,7 +434,6 @@ class _SingleInnerViewItemState extends State { child: FlowyText.regular( widget.view.name, overflow: TextOverflow.ellipsis, - lineHeight: 1.1, ), ), ]; @@ -466,7 +465,6 @@ class _SingleInnerViewItemState extends State { child: Padding( padding: EdgeInsets.only(left: widget.level * widget.leftPadding), child: Row( - mainAxisAlignment: MainAxisAlignment.center, children: children, ), ), @@ -499,7 +497,6 @@ class _SingleInnerViewItemState extends State { ? FlowyText.emoji( widget.view.icon.value, fontSize: 16.0, - lineHeight: 1.4, ) : Opacity(opacity: 0.6, child: widget.view.defaultIcon()); diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart index d5d04ddb98..71be43364f 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/text.dart @@ -3,8 +3,6 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; -const String _emojiFontFamily = 'noto color emoji'; - class FlowyText extends StatelessWidget { final String text; final TextOverflow? overflow; @@ -138,16 +136,13 @@ class FlowyText extends StatelessWidget { var fontFamily = this.fontFamily; var fallbackFontFamily = this.fallbackFontFamily; - if (isEmoji && (Platform.isLinux || Platform.isAndroid)) { + var fontSize = + this.fontSize ?? Theme.of(context).textTheme.bodyMedium!.fontSize!; + if (isEmoji && _useNotoColorEmoji) { fontFamily = _loadEmojiFontFamilyIfNeeded(); if (fontFamily != null && fallbackFontFamily == null) { fallbackFontFamily = [fontFamily]; } - } - - var fontSize = - this.fontSize ?? Theme.of(context).textTheme.bodyMedium!.fontSize!; - if (Platform.isLinux && fontFamily == _emojiFontFamily) { fontSize = fontSize * 0.8; } @@ -175,6 +170,14 @@ class FlowyText extends StatelessWidget { textAlign: textAlign, overflow: overflow ?? TextOverflow.clip, style: textStyle, + strutStyle: Platform.isMacOS + ? StrutStyle.fromTextStyle( + textStyle, + forceStrutHeight: true, + leadingDistribution: TextLeadingDistribution.even, + height: 1.1, + ) + : null, ); } @@ -189,10 +192,13 @@ class FlowyText extends StatelessWidget { } String? _loadEmojiFontFamilyIfNeeded() { - if (Platform.isLinux || Platform.isAndroid) { + if (_useNotoColorEmoji) { return GoogleFonts.notoColorEmoji().fontFamily; } return null; } + + bool get _useNotoColorEmoji => + Platform.isLinux || Platform.isAndroid || Platform.isWindows; } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart index 382b18fc0e..a50d500348 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/flowy_tooltip.dart @@ -25,6 +25,7 @@ class FlowyTooltip extends StatelessWidget { final isLightMode = Theme.of(context).brightness == Brightness.light; return Tooltip( margin: margin, + verticalOffset: 16.0, padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0), decoration: BoxDecoration( color: isLightMode ? const Color(0xE5171717) : const Color(0xE5E5E5E5), From 041e3c155af1c9685caec1c347cc183e3f4389bf Mon Sep 17 00:00:00 2001 From: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> Date: Wed, 5 Jun 2024 04:05:51 +0200 Subject: [PATCH 10/11] fix: search workspace sync indexing (#5437) * fix: search workspace sync indexing * chore: update collab rev temporarily * feat: revert comparison and implement index check * chore: fixes after merg * chore: enable search * chore: disable ai test --------- Co-authored-by: nathan --- .../lib/shared/feature_flags.dart | 2 +- .../lib/startup/tasks/app_widget.dart | 12 +- .../action_navigation_bloc.dart | 4 +- .../command_palette/command_palette_bloc.dart | 13 +- .../home/menu/sidebar/sidebar.dart | 5 +- frontend/appflowy_tauri/src-tauri/Cargo.lock | 2 + frontend/appflowy_web/wasm-libs/Cargo.lock | 240 +++++++++++++++++- .../appflowy_web_app/src-tauri/Cargo.lock | 1 + frontend/rust-lib/Cargo.lock | 2 + .../tests/chat/chat_message_test.rs | 58 ++--- .../src/deps_resolve/folder_deps.rs | 4 +- .../rust-lib/flowy-core/src/integrate/user.rs | 2 +- frontend/rust-lib/flowy-core/src/lib.rs | 6 +- frontend/rust-lib/flowy-folder/Cargo.toml | 3 +- .../flowy-folder/src/entities/workspace.rs | 5 + frontend/rust-lib/flowy-folder/src/manager.rs | 6 +- .../rust-lib/flowy-folder/src/manager_init.rs | 54 +++- .../rust-lib/flowy-search-pub/src/entities.rs | 12 + .../flowy-search/src/folder/indexer.rs | 10 +- 19 files changed, 368 insertions(+), 73 deletions(-) diff --git a/frontend/appflowy_flutter/lib/shared/feature_flags.dart b/frontend/appflowy_flutter/lib/shared/feature_flags.dart index 94b45da631..9f578c177a 100644 --- a/frontend/appflowy_flutter/lib/shared/feature_flags.dart +++ b/frontend/appflowy_flutter/lib/shared/feature_flags.dart @@ -102,9 +102,9 @@ enum FeatureFlag { switch (this) { case FeatureFlag.collaborativeWorkspace: case FeatureFlag.membersSettings: - case FeatureFlag.search: case FeatureFlag.unknown: return false; + case FeatureFlag.search: case FeatureFlag.syncDocument: case FeatureFlag.syncDatabase: return true; diff --git a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart index f90685f030..25b5b419b5 100644 --- a/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart +++ b/frontend/appflowy_flutter/lib/startup/tasks/app_widget.dart @@ -1,5 +1,8 @@ import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + import 'package:appflowy/mobile/application/mobile_router.dart'; import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart'; import 'package:appflowy/shared/feature_flags.dart'; @@ -13,6 +16,7 @@ import 'package:appflowy/workspace/application/notification/notification_service import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart'; import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart'; import 'package:appflowy/workspace/application/sidebar/rename_view/rename_view_bloc.dart'; +import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/presentation/command_palette/command_palette.dart'; import 'package:appflowy_backend/log.dart'; @@ -21,8 +25,6 @@ import 'package:appflowy_editor/appflowy_editor.dart' hide Log; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; @@ -175,8 +177,12 @@ class _ApplicationWidgetState extends State { if (action?.type == ActionType.openView && PlatformExtension.isDesktop) { final view = action!.arguments?[ActionArgumentKeys.view]; + final nodePath = action.arguments?[ActionArgumentKeys.nodePath]; if (view != null) { - AppGlobals.rootNavKey.currentContext?.pushView(view); + getIt().openPlugin( + view.plugin(), + arguments: {PluginArgumentKeys.selection: nodePath}, + ); } } else if (action?.type == ActionType.openRow && PlatformExtension.isMobile) { diff --git a/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart index 467115368d..5bc64b6785 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/action_navigation/action_navigation_bloc.dart @@ -21,11 +21,11 @@ class ActionNavigationBloc currentAction = currentAction.copyWith(arguments: {}); } - action.arguments?.addAll({ActionArgumentKeys.view: view}); + currentAction.arguments?.addAll({ActionArgumentKeys.view: view}); } } - emit(state.copyWith(action: action, nextActions: nextActions)); + emit(state.copyWith(action: currentAction, nextActions: nextActions)); if (nextActions.isNotEmpty) { final newActions = [...nextActions]; diff --git a/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart b/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart index 0c45cd8bf4..03a35836e9 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/command_palette/command_palette_bloc.dart @@ -101,22 +101,15 @@ class CommandPaletteBloc Future _initTrash() async { _trashListener.start( trashUpdated: (trashOrFailed) { - final trash = trashOrFailed.fold( - (trash) => trash, - (error) => null, - ); - + final trash = trashOrFailed.toNullable(); add(CommandPaletteEvent.trashChanged(trash: trash)); }, ); final trashOrFailure = await _trashService.readTrash(); - final trashRes = trashOrFailure.fold( - (trash) => trash, - (error) => null, - ); + final trash = trashOrFailure.toNullable(); - add(CommandPaletteEvent.trashChanged(trash: trashRes?.items)); + add(CommandPaletteEvent.trashChanged(trash: trash?.items)); } void _debounceOnSearchChanged(String value) { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart index 6956bc51d6..fe8b0db70b 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/menu/sidebar/sidebar.dart @@ -1,5 +1,7 @@ import 'dart:async'; +import 'package:flutter/material.dart'; + import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/shared/feature_flags.dart'; @@ -30,7 +32,6 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; /// Home Sidebar is the left side bar of the home page. @@ -95,7 +96,7 @@ class HomeSideBar extends StatelessWidget { } return MultiBlocProvider( providers: [ - BlocProvider(create: (_) => getIt()), + BlocProvider.value(value: getIt()), BlocProvider( create: (_) => SidebarSectionsBloc() ..add( diff --git a/frontend/appflowy_tauri/src-tauri/Cargo.lock b/frontend/appflowy_tauri/src-tauri/Cargo.lock index 0c48e8f203..6a94085951 100644 --- a/frontend/appflowy_tauri/src-tauri/Cargo.lock +++ b/frontend/appflowy_tauri/src-tauri/Cargo.lock @@ -2129,12 +2129,14 @@ dependencies = [ "flowy-folder-pub", "flowy-notification", "flowy-search-pub", + "flowy-sqlite", "lazy_static", "lib-dispatch", "lib-infra", "nanoid", "parking_lot 0.12.1", "protobuf", + "serde", "serde_json", "strum_macros 0.21.1", "tokio", diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index b8da195c3d..d93af21f59 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -1004,6 +1004,41 @@ dependencies = [ "cipher", ] +[[package]] +name = "darling" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.48", +] + +[[package]] +name = "darling_macro" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.48", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -1091,6 +1126,53 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" +[[package]] +name = "diesel" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35b696af9ff4c0d2a507db2c5faafa8aa0205e297e5f11e203a24226d5355e7a" +dependencies = [ + "chrono", + "diesel_derives", + "libsqlite3-sys", + "r2d2", + "serde_json", + "time", +] + +[[package]] +name = "diesel_derives" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6fdd83d5947068817016e939596d246e5367279453f2a3433287894f2f2996" +dependencies = [ + "diesel_table_macro_syntax", + "dsl_auto_type", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "diesel_migrations" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a73ce704bad4231f001bff3314d91dce4aba0770cee8b233991859abc15c1f6" +dependencies = [ + "diesel", + "migrations_internals", + "migrations_macros", +] + +[[package]] +name = "diesel_table_macro_syntax" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" +dependencies = [ + "syn 2.0.48", +] + [[package]] name = "digest" version = "0.10.7" @@ -1102,6 +1184,20 @@ dependencies = [ "subtle", ] +[[package]] +name = "dsl_auto_type" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab32c18ea6760d951659768a3e35ea72fc1ba0916d665a88dfe048b2a41e543f" +dependencies = [ + "darling", + "either", + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "dtoa" version = "1.0.9" @@ -1286,7 +1382,7 @@ dependencies = [ "similar 1.3.0", "syn 1.0.109", "tera", - "toml", + "toml 0.5.11", "walkdir", ] @@ -1421,12 +1517,14 @@ dependencies = [ "flowy-folder-pub", "flowy-notification", "flowy-search-pub", + "flowy-sqlite", "lazy_static", "lib-dispatch", "lib-infra", "nanoid", "parking_lot 0.12.1", "protobuf", + "serde", "serde_json", "strum_macros 0.21.1", "tokio", @@ -1532,6 +1630,24 @@ dependencies = [ "serde_repr", ] +[[package]] +name = "flowy-sqlite" +version = "0.1.0" +dependencies = [ + "anyhow", + "diesel", + "diesel_derives", + "diesel_migrations", + "libsqlite3-sys", + "parking_lot 0.12.1", + "r2d2", + "scheduled-thread-pool", + "serde", + "serde_json", + "thiserror", + "tracing", +] + [[package]] name = "flowy-storage" version = "0.1.0" @@ -1883,6 +1999,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.4" @@ -2050,6 +2172,12 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.3.0" @@ -2321,6 +2449,17 @@ dependencies = [ "zstd-sys", ] +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "libz-sys" version = "1.1.14" @@ -2439,6 +2578,27 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" +[[package]] +name = "migrations_internals" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd01039851e82f8799046eabbb354056283fb265c8ec0996af940f4e85a380ff" +dependencies = [ + "serde", + "toml 0.8.14", +] + +[[package]] +name = "migrations_macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb161cc72176cb37aa47f1fc520d3ef02263d67d661f44f05d05a079e1237fd" +dependencies = [ + "migrations_internals", + "proc-macro2", + "quote", +] + [[package]] name = "mime" version = "0.3.17" @@ -3237,6 +3397,17 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r2d2" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" +dependencies = [ + "log", + "parking_lot 0.12.1", + "scheduled-thread-pool", +] + [[package]] name = "rand" version = "0.7.3" @@ -3545,6 +3716,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "scheduled-thread-pool" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" +dependencies = [ + "parking_lot 0.12.1", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -3712,6 +3892,15 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "serde_spanned" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3917,6 +4106,12 @@ dependencies = [ "quote", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "strum_macros" version = "0.21.1" @@ -4254,6 +4449,40 @@ dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -4943,6 +5172,15 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "winnow" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c52728401e1dc672a56e81e593e912aa54c78f40246869f78359a2bf24d29d" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/frontend/appflowy_web_app/src-tauri/Cargo.lock b/frontend/appflowy_web_app/src-tauri/Cargo.lock index d7aaa79525..2ba17e8683 100644 --- a/frontend/appflowy_web_app/src-tauri/Cargo.lock +++ b/frontend/appflowy_web_app/src-tauri/Cargo.lock @@ -2166,6 +2166,7 @@ dependencies = [ "flowy-folder-pub", "flowy-notification", "flowy-search-pub", + "flowy-sqlite", "lazy_static", "lib-dispatch", "lib-infra", diff --git a/frontend/rust-lib/Cargo.lock b/frontend/rust-lib/Cargo.lock index b98f682a2c..e3570807f0 100644 --- a/frontend/rust-lib/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -1968,12 +1968,14 @@ dependencies = [ "flowy-folder-pub", "flowy-notification", "flowy-search-pub", + "flowy-sqlite", "lazy_static", "lib-dispatch", "lib-infra", "nanoid", "parking_lot 0.12.1", "protobuf", + "serde", "serde_json", "strum_macros 0.21.1", "tokio", diff --git a/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs b/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs index 1efe4c77d0..8594193ab6 100644 --- a/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs +++ b/frontend/rust-lib/event-integration-test/tests/chat/chat_message_test.rs @@ -1,7 +1,7 @@ use crate::util::receive_with_timeout; use event_integration_test::user_event::user_localhost_af_cloud; use event_integration_test::EventIntegrationTest; -use flowy_chat::entities::{ChatMessageListPB, ChatMessageTypePB}; +use flowy_chat::entities::ChatMessageListPB; use flowy_chat::notification::ChatNotification; use flowy_chat_pub::cloud::ChatMessageType; @@ -131,31 +131,31 @@ async fn af_cloud_load_remote_system_message_test() { assert_eq!(first_five_messages.messages[4].content, "hello server 0"); } -#[tokio::test] -async fn af_cloud_load_remote_user_message_test() { - user_localhost_af_cloud().await; - let test = EventIntegrationTest::new().await; - test.af_cloud_sign_up().await; - - let current_workspace = test.get_current_workspace().await; - let view = test.create_chat(¤t_workspace.id).await; - let chat_id = view.id.clone(); - let rx = test - .notification_sender - .subscribe_without_payload(&chat_id, ChatNotification::FinishAnswerQuestion); - test - .send_message(&chat_id, "hello world", ChatMessageTypePB::User) - .await; - let _ = receive_with_timeout(rx, Duration::from_secs(60)) - .await - .unwrap(); - - let all = test.load_next_message(&chat_id, 5, None).await; - assert_eq!(all.messages.len(), 2); - // 3 means AI - assert_eq!(all.messages[0].author_type, 3); - // 2 means User - assert_eq!(all.messages[1].author_type, 1); - // The message ID is incremented by 1. - assert_eq!(all.messages[1].message_id + 1, all.messages[0].message_id); -} +// #[tokio::test] +// async fn af_cloud_load_remote_user_message_test() { +// user_localhost_af_cloud().await; +// let test = EventIntegrationTest::new().await; +// test.af_cloud_sign_up().await; +// +// let current_workspace = test.get_current_workspace().await; +// let view = test.create_chat(¤t_workspace.id).await; +// let chat_id = view.id.clone(); +// let rx = test +// .notification_sender +// .subscribe_without_payload(&chat_id, ChatNotification::FinishAnswerQuestion); +// test +// .send_message(&chat_id, "hello world", ChatMessageTypePB::User) +// .await; +// let _ = receive_with_timeout(rx, Duration::from_secs(60)) +// .await +// .unwrap(); +// +// let all = test.load_next_message(&chat_id, 5, None).await; +// assert_eq!(all.messages.len(), 2); +// // 3 means AI +// assert_eq!(all.messages[0].author_type, 3); +// // 2 means User +// assert_eq!(all.messages[1].author_type, 1); +// // The message ID is incremented by 1. +// assert_eq!(all.messages[1].message_id + 1, all.messages[0].message_id); +// } diff --git a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs index 92e09996d5..e826a3f4c4 100644 --- a/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-core/src/deps_resolve/folder_deps.rs @@ -18,6 +18,7 @@ use flowy_folder::view_operation::{ use flowy_folder::ViewLayout; use flowy_folder_pub::folder_builder::NestedViewBuilder; use flowy_search::folder::indexer::FolderIndexManagerImpl; +use flowy_sqlite::kv::StorePreferences; use flowy_user::services::authenticate_user::AuthenticateUser; use lib_dispatch::prelude::ToBytes; use lib_infra::future::FutureResult; @@ -37,6 +38,7 @@ impl FolderDepsResolver { collab_builder: Arc, server_provider: Arc, folder_indexer: Arc, + store_preferences: Arc, chat_manager: &Arc, ) -> Arc { let user: Arc = Arc::new(FolderUserImpl { @@ -55,8 +57,8 @@ impl FolderDepsResolver { handlers, server_provider.clone(), folder_indexer, + store_preferences, ) - .await .unwrap(), ) } diff --git a/frontend/rust-lib/flowy-core/src/integrate/user.rs b/frontend/rust-lib/flowy-core/src/integrate/user.rs index b68e54f2dc..f8219cdaff 100644 --- a/frontend/rust-lib/flowy-core/src/integrate/user.rs +++ b/frontend/rust-lib/flowy-core/src/integrate/user.rs @@ -1,9 +1,9 @@ use std::sync::Arc; use anyhow::Context; -use collab_entity::CollabType; use tracing::event; +use collab_entity::CollabType; use collab_integrate::collab_builder::AppFlowyCollabBuilder; use flowy_database2::DatabaseManager; use flowy_document::manager::DocumentManager; diff --git a/frontend/rust-lib/flowy-core/src/lib.rs b/frontend/rust-lib/flowy-core/src/lib.rs index 80bb1213f5..02f63c6f1d 100644 --- a/frontend/rust-lib/flowy-core/src/lib.rs +++ b/frontend/rust-lib/flowy-core/src/lib.rs @@ -169,7 +169,10 @@ impl AppFlowyCore { let chat_manager = ChatDepsResolver::resolve(Arc::downgrade(&authenticate_user), server_provider.clone()); - let folder_indexer = Arc::new(FolderIndexManagerImpl::new(None)); + + let folder_indexer = Arc::new(FolderIndexManagerImpl::new(Some(Arc::downgrade( + &authenticate_user, + )))); let folder_manager = FolderDepsResolver::resolve( Arc::downgrade(&authenticate_user), &document_manager, @@ -177,6 +180,7 @@ impl AppFlowyCore { collab_builder.clone(), server_provider.clone(), folder_indexer.clone(), + store_preference.clone(), &chat_manager, ) .await; diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index ba4a2e3481..c80a0bfdde 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -14,7 +14,7 @@ collab-plugins = { workspace = true } collab-integrate = { workspace = true } flowy-folder-pub = { workspace = true } flowy-search-pub = { workspace = true } - +flowy-sqlite = { workspace = true } flowy-derive.workspace = true flowy-notification = { workspace = true } parking_lot.workspace = true @@ -35,6 +35,7 @@ strum_macros = "0.21" protobuf.workspace = true uuid.workspace = true tokio-stream = { workspace = true, features = ["sync"] } +serde = { workspace = true, features = ["derive"]} serde_json.workspace = true validator = "0.16.0" async-trait.workspace = true diff --git a/frontend/rust-lib/flowy-folder/src/entities/workspace.rs b/frontend/rust-lib/flowy-folder/src/entities/workspace.rs index 21ff046226..e78eb6e307 100644 --- a/frontend/rust-lib/flowy-folder/src/entities/workspace.rs +++ b/frontend/rust-lib/flowy-folder/src/entities/workspace.rs @@ -232,3 +232,8 @@ pub struct UserFolderPB { #[pb(index = 2)] pub workspace_id: String, } + +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Eq, PartialEq)] +pub struct IndexedWorkspaceIds { + pub workspace_ids: Vec, +} diff --git a/frontend/rust-lib/flowy-folder/src/manager.rs b/frontend/rust-lib/flowy-folder/src/manager.rs index b3a8f6a1f3..71be3778ee 100644 --- a/frontend/rust-lib/flowy-folder/src/manager.rs +++ b/frontend/rust-lib/flowy-folder/src/manager.rs @@ -30,6 +30,7 @@ use flowy_error::{ErrorCode, FlowyError, FlowyResult}; use flowy_folder_pub::cloud::{gen_view_id, FolderCloudService}; use flowy_folder_pub::folder_builder::ParentChildViews; use flowy_search_pub::entities::FolderIndexManager; +use flowy_sqlite::kv::StorePreferences; use parking_lot::RwLock; use std::fmt::{Display, Formatter}; use std::ops::Deref; @@ -50,15 +51,17 @@ pub struct FolderManager { pub(crate) operation_handlers: FolderOperationHandlers, pub cloud_service: Arc, pub(crate) folder_indexer: Arc, + pub(crate) store_preferences: Arc, } impl FolderManager { - pub async fn new( + pub fn new( user: Arc, collab_builder: Arc, operation_handlers: FolderOperationHandlers, cloud_service: Arc, folder_indexer: Arc, + store_preferences: Arc, ) -> FlowyResult { let mutex_folder = Arc::new(MutexFolder::default()); let manager = Self { @@ -68,6 +71,7 @@ impl FolderManager { operation_handlers, cloud_service, folder_indexer, + store_preferences, }; Ok(manager) diff --git a/frontend/rust-lib/flowy-folder/src/manager_init.rs b/frontend/rust-lib/flowy-folder/src/manager_init.rs index 6332a683ff..07fc973f05 100644 --- a/frontend/rust-lib/flowy-folder/src/manager_init.rs +++ b/frontend/rust-lib/flowy-folder/src/manager_init.rs @@ -1,3 +1,4 @@ +use crate::entities::IndexedWorkspaceIds; use crate::manager::{FolderInitDataSource, FolderManager}; use crate::manager_observer::*; use crate::user_default::DefaultFolderBuilder; @@ -10,6 +11,8 @@ use std::sync::{Arc, Weak}; use tokio::task::spawn_blocking; use tracing::{event, info, Level}; +pub const INDEXED_WORKSPACE_KEY: &str = "indexed-workspace-ids"; + impl FolderManager { /// Called immediately after the application launched if the user already sign in/sign up. #[tracing::instrument(level = "info", skip(self, initial_data), err)] @@ -118,18 +121,7 @@ impl FolderManager { self .folder_indexer .set_index_content_receiver(index_content_rx, workspace_id.clone()); - - // Index all views in the folder if needed - if !self.folder_indexer.is_indexed() { - let views = folder.views.get_all_views(); - let folder_indexer = self.folder_indexer.clone(); - - // We spawn a blocking task to index all views in the folder - let wid = workspace_id.clone(); - spawn_blocking(move || { - folder_indexer.index_all_views(views, wid); - }); - } + self.handle_index_folder(workspace_id.clone(), &folder); *self.mutex_folder.write() = Some(folder); @@ -156,6 +148,7 @@ impl FolderManager { &weak_mutex_folder, Arc::downgrade(&self.user), ); + Ok(()) } @@ -192,4 +185,41 @@ impl FolderManager { folder_data, )) } + + fn handle_index_folder(&self, workspace_id: String, folder: &Folder) { + let index_all; + if self.folder_indexer.is_indexed() { + // If indexes already exist, we check if the workspace was + // previously indexed, if it wasn't we index all + let indexed_ids = self + .store_preferences + .get_object::(INDEXED_WORKSPACE_KEY); + if let Some(indexed_ids) = indexed_ids { + index_all = !indexed_ids.workspace_ids.contains(&workspace_id.clone()); + if !index_all { + let mut workspace_ids = indexed_ids.workspace_ids.clone(); + workspace_ids.push(workspace_id.clone()); + let _ = self + .store_preferences + .set_object(INDEXED_WORKSPACE_KEY, IndexedWorkspaceIds { workspace_ids }); + } + } else { + index_all = true; + } + } else { + // If there exists no indexes, we index all views in workspace + index_all = true; + } + + if index_all { + let views = folder.views.get_all_views(); + let folder_indexer = self.folder_indexer.clone(); + let wid = workspace_id.clone(); + + // We spawn a blocking task to index all views in the folder + spawn_blocking(move || { + folder_indexer.index_all_views(views, wid); + }); + } + } } diff --git a/frontend/rust-lib/flowy-search-pub/src/entities.rs b/frontend/rust-lib/flowy-search-pub/src/entities.rs index dfa741bf50..8b9b4a3cb6 100644 --- a/frontend/rust-lib/flowy-search-pub/src/entities.rs +++ b/frontend/rust-lib/flowy-search-pub/src/entities.rs @@ -13,6 +13,18 @@ pub struct IndexableData { pub workspace_id: String, } +impl IndexableData { + pub fn from_view(view: Arc, workspace_id: String) -> Self { + IndexableData { + id: view.id.clone(), + data: view.name.clone(), + icon: view.icon.clone(), + layout: view.layout.clone(), + workspace_id: workspace_id.clone(), + } + } +} + pub trait IndexManager: Send + Sync { fn set_index_content_receiver(&self, rx: IndexContentReceiver, workspace_id: String); fn add_index(&self, data: IndexableData) -> Result<(), FlowyError>; diff --git a/frontend/rust-lib/flowy-search/src/folder/indexer.rs b/frontend/rust-lib/flowy-search/src/folder/indexer.rs index 834efe949a..39192806b8 100644 --- a/frontend/rust-lib/flowy-search/src/folder/indexer.rs +++ b/frontend/rust-lib/flowy-search/src/folder/indexer.rs @@ -124,7 +124,7 @@ impl FolderIndexManagerImpl { } fn index_all(&self, indexes: Vec) -> Result<(), FlowyError> { - if self.is_indexed() || indexes.is_empty() { + if indexes.is_empty() { return Ok(()); } @@ -411,13 +411,7 @@ impl FolderIndexManager for FolderIndexManagerImpl { fn index_all_views(&self, views: Vec>, workspace_id: String) { let indexable_data = views .into_iter() - .map(|view| IndexableData { - id: view.id.clone(), - data: view.name.clone(), - icon: view.icon.clone(), - layout: view.layout.clone(), - workspace_id: workspace_id.clone(), - }) + .map(|view| IndexableData::from_view(view, workspace_id.clone())) .collect(); let _ = self.index_all(indexable_data); From a0e981ec6b0ec8bd47b8aca6b4ae0964b5983ac8 Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 5 Jun 2024 11:21:24 +0800 Subject: [PATCH 11/11] chore: downgrade diesel version in appflowy web --- frontend/appflowy_web/wasm-libs/Cargo.lock | 106 ++++----------------- 1 file changed, 19 insertions(+), 87 deletions(-) diff --git a/frontend/appflowy_web/wasm-libs/Cargo.lock b/frontend/appflowy_web/wasm-libs/Cargo.lock index d93af21f59..15c6119e02 100644 --- a/frontend/appflowy_web/wasm-libs/Cargo.lock +++ b/frontend/appflowy_web/wasm-libs/Cargo.lock @@ -1004,41 +1004,6 @@ dependencies = [ "cipher", ] -[[package]] -name = "darling" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.48", -] - -[[package]] -name = "darling_macro" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.48", -] - [[package]] name = "dashmap" version = "5.5.3" @@ -1128,9 +1093,9 @@ checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" [[package]] name = "diesel" -version = "2.2.0" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35b696af9ff4c0d2a507db2c5faafa8aa0205e297e5f11e203a24226d5355e7a" +checksum = "62c6fcf842f17f8c78ecf7c81d75c5ce84436b41ee07e03f490fbb5f5a8731d8" dependencies = [ "chrono", "diesel_derives", @@ -1142,12 +1107,11 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6fdd83d5947068817016e939596d246e5367279453f2a3433287894f2f2996" +checksum = "ef8337737574f55a468005a83499da720f20c65586241ffea339db9ecdfd2b44" dependencies = [ "diesel_table_macro_syntax", - "dsl_auto_type", "proc-macro2", "quote", "syn 2.0.48", @@ -1155,9 +1119,9 @@ dependencies = [ [[package]] name = "diesel_migrations" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a73ce704bad4231f001bff3314d91dce4aba0770cee8b233991859abc15c1f6" +checksum = "6036b3f0120c5961381b570ee20a02432d7e2d27ea60de9578799cf9156914ac" dependencies = [ "diesel", "migrations_internals", @@ -1166,9 +1130,9 @@ dependencies = [ [[package]] name = "diesel_table_macro_syntax" -version = "0.2.0" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" +checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ "syn 2.0.48", ] @@ -1184,20 +1148,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "dsl_auto_type" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab32c18ea6760d951659768a3e35ea72fc1ba0916d665a88dfe048b2a41e543f" -dependencies = [ - "darling", - "either", - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "dtoa" version = "1.0.9" @@ -1999,12 +1949,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - [[package]] name = "hermit-abi" version = "0.3.4" @@ -2172,12 +2116,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.3.0" @@ -2580,19 +2518,19 @@ checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" [[package]] name = "migrations_internals" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd01039851e82f8799046eabbb354056283fb265c8ec0996af940f4e85a380ff" +checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada" dependencies = [ "serde", - "toml 0.8.14", + "toml 0.7.8", ] [[package]] name = "migrations_macros" -version = "2.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb161cc72176cb37aa47f1fc520d3ef02263d67d661f44f05d05a079e1237fd" +checksum = "cce3325ac70e67bbab5bd837a31cae01f1a6db64e0e744a33cb03a543469ef08" dependencies = [ "migrations_internals", "proc-macro2", @@ -4106,12 +4044,6 @@ dependencies = [ "quote", ] -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - [[package]] name = "strum_macros" version = "0.21.1" @@ -4451,9 +4383,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", @@ -4472,9 +4404,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap", "serde", @@ -5174,9 +5106,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.6.11" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c52728401e1dc672a56e81e593e912aa54c78f40246869f78359a2bf24d29d" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ]