From 177cca60c4587bb21106f07df1ac14f3be4e280e Mon Sep 17 00:00:00 2001 From: Mathias Mogensen <42929161+Xazin@users.noreply.github.com> Date: Sun, 10 Dec 2023 13:44:37 +0200 Subject: [PATCH] fix: notes disappears (#4122) --- .../lib/plugins/base/emoji/emoji_text.dart | 3 + .../field/type_option/number_format_bloc.dart | 2 +- .../board/presentation/board_page.dart | 50 +++--- .../grid/presentation/grid_page.dart | 1 - .../database_view/widgets/card/card.dart | 16 +- .../widgets/card/cells/text_card_cell.dart | 10 +- .../card/container/card_container.dart | 20 ++- .../lib/plugins/document/document.dart | 3 +- .../document/presentation/editor_page.dart | 1 - .../editor_plugins/base/color_extension.dart | 1 - .../image/upload_image_menu.dart | 2 +- .../mention/mention_page_block.dart | 35 ++-- .../openai/service/openai_client.dart | 3 - .../presentation/more/more_button.dart | 14 +- .../handlers/inline_page_reference.dart | 11 +- .../lib/util/either_extension.dart | 6 - .../lib/util/theme_mode_extension.dart | 18 +- .../workspace/application/view/view_ext.dart | 158 ++++++------------ .../presentation/home/home_stack.dart | 10 +- .../home/menu/view/view_item.dart | 4 +- .../notifications/notification_dialog.dart | 2 - .../lib/style_widget/extension.dart | 24 --- .../flowy_infra_ui/lib/style_widget/text.dart | 38 +++-- .../lib/widget/clickable_extension.dart | 15 -- frontend/resources/translations/en.json | 5 + 25 files changed, 191 insertions(+), 261 deletions(-) delete mode 100644 frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/color_extension.dart delete mode 100644 frontend/appflowy_flutter/lib/util/either_extension.dart delete mode 100644 frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/clickable_extension.dart diff --git a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_text.dart b/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_text.dart index 047626d8e9..e9fed800d4 100644 --- a/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_text.dart +++ b/frontend/appflowy_flutter/lib/plugins/base/emoji/emoji_text.dart @@ -14,11 +14,13 @@ class EmojiText extends StatelessWidget { required this.emoji, required this.fontSize, this.textAlign, + this.lineHeight, }); final String emoji; final double fontSize; final TextAlign? textAlign; + final double? lineHeight; @override Widget build(BuildContext context) { @@ -28,6 +30,7 @@ class EmojiText extends StatelessWidget { fontSize: fontSize, textAlign: textAlign, fallbackFontFamily: _cachedFallbackFontFamily, + lineHeight: lineHeight, ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/application/field/type_option/number_format_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database_view/application/field/type_option/number_format_bloc.dart index b6932ce0ac..176a638afc 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/application/field/type_option/number_format_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/application/field/type_option/number_format_bloc.dart @@ -61,7 +61,7 @@ extension NumberFormatExtension on NumberFormatPB { case NumberFormatPB.ColombianPeso: return "Colombian peso"; case NumberFormatPB.DanishKrone: - return "Danish krone"; + return "Danish crown"; case NumberFormatPB.Dirham: return "Dirham"; case NumberFormatPB.EUR: diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart index 3a3c0ced4c..fdcf65a7ad 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/board/presentation/board_page.dart @@ -208,20 +208,27 @@ class _DesktopBoardContentState extends State { } Widget _buildFooter(BuildContext context, AppFlowyGroupData columnData) { - return AppFlowyGroupFooter( - height: 36, - margin: config.groupFooterPadding, - icon: FlowySvg( - FlowySvgs.add_s, - color: Theme.of(context).hintColor, + return Padding( + padding: config.groupFooterPadding, + child: FlowyTooltip( + message: LocaleKeys.board_column_addToColumnBottomTooltip.tr(), + child: FlowyHover( + child: AppFlowyGroupFooter( + height: 36, + icon: FlowySvg( + FlowySvgs.add_s, + color: Theme.of(context).hintColor, + ), + title: FlowyText.medium( + LocaleKeys.board_column_createNewCard.tr(), + color: Theme.of(context).hintColor, + ), + onAddButtonClick: () => context + .read() + .add(BoardEvent.createBottomRow(columnData.id)), + ), + ), ), - title: FlowyText.medium( - LocaleKeys.board_column_createNewCard.tr(), - color: Theme.of(context).hintColor, - ), - onAddButtonClick: () => context - .read() - .add(BoardEvent.createBottomRow(columnData.id)), ); } @@ -233,11 +240,14 @@ class _DesktopBoardContentState extends State { final boardBloc = context.read(); final groupItem = afGroupItem as GroupItem; final groupData = afGroupData.customData as GroupData; - final rowMeta = groupItem.row; final rowCache = boardBloc.getRowCache(); + final rowInfo = rowCache?.getRow(groupItem.row.id); + + /// Return placeholder widget if the rowCache or rowInfo is null. + if (rowCache == null) { + return SizedBox.shrink(key: ObjectKey(groupItem)); + } - /// Return placeholder widget if the rowCache is null. - if (rowCache == null) return SizedBox.shrink(key: ObjectKey(groupItem)); final cellCache = rowCache.cellCache; final fieldController = boardBloc.fieldController; final viewId = boardBloc.viewId; @@ -247,6 +257,7 @@ class _DesktopBoardContentState extends State { boardBloc.state.editingRow?.row.id == groupItem.row.id; final groupItemId = "${groupData.group.groupId}${groupItem.row.id}"; + final rowMeta = rowInfo?.rowMeta ?? groupItem.row; return AppFlowyGroupCard( key: ValueKey(groupItemId), @@ -278,10 +289,9 @@ class _DesktopBoardContentState extends State { foregroundColorOnHover: Theme.of(context).colorScheme.onBackground, ), ), - onStartEditing: () => boardBloc - .add(BoardEvent.startEditingRow(groupData.group, groupItem.row)), - onEndEditing: () => - boardBloc.add(BoardEvent.endEditingRow(groupItem.row.id)), + onStartEditing: () => + boardBloc.add(BoardEvent.startEditingRow(groupData.group, rowMeta)), + onEndEditing: () => boardBloc.add(BoardEvent.endEditingRow(rowMeta.id)), ), ); } diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/grid_page.dart b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/grid_page.dart index 837b5f3da2..1178277f12 100755 --- a/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/grid_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/grid/presentation/grid_page.dart @@ -258,7 +258,6 @@ class _GridRows extends StatelessWidget { }).toList() ..add(const GridRowBottomBar(key: Key('gridFooter'))); return ReorderableListView.builder( - /// TODO(Xazin): Resolve inconsistent scrollbar behavior /// This is a workaround related to /// https://github.com/flutter/flutter/issues/25652 cacheExtent: 5000, diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart index 1129e937e8..6dc1144dca 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/card.dart @@ -141,13 +141,11 @@ class _RowCardState extends State> { triggerActions: PopoverTriggerFlags.none, constraints: BoxConstraints.loose(const Size(140, 200)), direction: PopoverDirection.rightWithCenterAligned, - popupBuilder: (popoverContext) { - return RowActions( - viewId: _cardBloc.viewId, - rowId: _cardBloc.rowMeta.id, - groupId: widget.groupId, - ); - }, + popupBuilder: (_) => RowActions( + viewId: _cardBloc.viewId, + rowId: _cardBloc.rowMeta.id, + groupId: widget.groupId, + ), child: RowCardContainer( buildAccessoryWhen: () => state.isEditing == false, accessories: [ @@ -203,12 +201,12 @@ class _CardContent extends StatefulWidget { this.renderHook, }); - final CardCellBuilder cellBuilder; final EditableRowNotifier rowNotifier; + final CardCellBuilder cellBuilder; final List cells; - final RowCardRenderHook? renderHook; final CustomCardData? cardData; final RowCardStyleConfiguration styleConfiguration; + final RowCardRenderHook? renderHook; @override State<_CardContent> createState() => diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/text_card_cell.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/text_card_cell.dart index 53a3347f60..735b8d8b23 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/text_card_cell.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/cells/text_card_cell.dart @@ -4,6 +4,7 @@ import 'package:appflowy/plugins/database_view/application/cell/cell_controller_ import 'package:appflowy/plugins/database_view/widgets/row/cells/text_cell/text_cell_bloc.dart'; import 'package:easy_localization/easy_localization.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_bloc/flutter_bloc.dart'; @@ -142,9 +143,12 @@ class _TextCellState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ if (widget.showNotes) ...[ - FlowySvg( - FlowySvgs.notes_s, - color: Theme.of(context).hintColor, + FlowyTooltip( + message: LocaleKeys.board_notesTooltip.tr(), + child: FlowySvg( + FlowySvgs.notes_s, + color: Theme.of(context).hintColor, + ), ), const HSpace(4), ], diff --git a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/card_container.dart b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/card_container.dart index 77ec57014a..af95357260 100644 --- a/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/card_container.dart +++ b/frontend/appflowy_flutter/lib/plugins/database_view/widgets/card/container/card_container.dart @@ -4,20 +4,21 @@ import 'package:provider/provider.dart'; import 'accessory.dart'; class RowCardContainer extends StatelessWidget { - final Widget child; - final List accessories; - final bool Function()? buildAccessoryWhen; - final void Function(BuildContext) openCard; - final void Function(AccessoryType) openAccessory; const RowCardContainer({ + super.key, required this.child, required this.openCard, required this.openAccessory, required this.accessories, this.buildAccessoryWhen, - super.key, }); + final Widget child; + final void Function(BuildContext) openCard; + final void Function(AccessoryType) openAccessory; + final List accessories; + final bool Function()? buildAccessoryWhen; + @override Widget build(BuildContext context) { return ChangeNotifierProvider( @@ -53,15 +54,16 @@ class RowCardContainer extends StatelessWidget { } class _CardEnterRegion extends StatelessWidget { - final Widget child; - final List accessories; - final void Function(AccessoryType) onTapAccessory; const _CardEnterRegion({ required this.child, required this.accessories, required this.onTapAccessory, }); + final Widget child; + final List accessories; + final void Function(AccessoryType) onTapAccessory; + @override Widget build(BuildContext context) { return Selector<_CardContainerNotifier, bool>( diff --git a/frontend/appflowy_flutter/lib/plugins/document/document.dart b/frontend/appflowy_flutter/lib/plugins/document/document.dart index bc0b6fe2eb..f93678caf8 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/document.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/document.dart @@ -13,6 +13,7 @@ import 'package:appflowy/workspace/presentation/widgets/tab_bar_item.dart'; import 'package:appflowy/workspace/presentation/widgets/view_title_bar.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/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'; @@ -117,7 +118,7 @@ class DocumentPluginWidgetBuilder extends PluginWidgetBuilder key: ValueKey(view.id), view: view, ), - const SizedBox(width: 10), + const HSpace(4), const DocumentMoreButton(), ], ); diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart index a4c5192387..c201d455de 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_page.dart @@ -398,7 +398,6 @@ class _AppFlowyEditorPageState extends State { } Future _initializeShortcuts() async { - // TODO(Xazin): Refactor lazy initialization defaultCommandShortcutEvents; final settingsShortcutService = SettingsShortcutService(); final customizeShortcuts = diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/color_extension.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/color_extension.dart deleted file mode 100644 index 8b13789179..0000000000 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/base/color_extension.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/upload_image_menu.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/upload_image_menu.dart index becbe80a81..7e63f3b4da 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/upload_image_menu.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/image/upload_image_menu.dart @@ -29,7 +29,7 @@ enum UploadImageType { case UploadImageType.url: return LocaleKeys.document_imageBlock_embedLink_label.tr(); case UploadImageType.unsplash: - return 'Unsplash'; + return LocaleKeys.document_imageBlock_unsplash_label.tr(); case UploadImageType.openAI: return LocaleKeys.document_imageBlock_ai_label.tr(); case UploadImageType.stabilityAI: diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart index 629e025491..4b4c1b0a21 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart @@ -1,4 +1,5 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; +import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; import 'package:appflowy/plugins/trash/application/trash_service.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; @@ -33,8 +34,8 @@ class MentionPageBlock extends StatefulWidget { class _MentionPageBlockState extends State { late final EditorState editorState; + late final ViewListener viewListener = ViewListener(viewId: widget.pageId); late Future viewPBFuture; - ViewListener? viewListener; @override void initState() { @@ -42,19 +43,18 @@ class _MentionPageBlockState extends State { editorState = context.read(); viewPBFuture = fetchView(widget.pageId); - viewListener = ViewListener(viewId: widget.pageId) - ..start( - onViewUpdated: (p0) { - pageMemorizer[p0.id] = p0; - viewPBFuture = fetchView(widget.pageId); - editorState.reload(); - }, - ); + viewListener.start( + onViewUpdated: (p0) { + pageMemorizer[p0.id] = p0; + viewPBFuture = fetchView(widget.pageId); + editorState.reload(); + }, + ); } @override void dispose() { - viewListener?.stop(); + viewListener.stop(); super.dispose(); } @@ -83,10 +83,17 @@ class _MentionPageBlockState extends State { mainAxisSize: MainAxisSize.min, children: [ const HSpace(4), - FlowySvg( - view.layout.icon, - size: Size.square(iconSize + 2.0), - ), + view.icon.value.isNotEmpty + ? EmojiText( + emoji: view.icon.value, + fontSize: 12, + textAlign: TextAlign.center, + lineHeight: 1.3, + ) + : FlowySvg( + view.layout.icon, + size: Size.square(iconSize + 2.0), + ), const HSpace(2), FlowyText( view.name, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart index 71dfefe16b..d6823c33ad 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/editor_plugins/openai/service/openai_client.dart @@ -8,9 +8,6 @@ import 'package:http/http.dart' as http; import 'error.dart'; import 'text_completion.dart'; -// Please fill in your own API key -const apiKey = ''; - enum OpenAIRequestType { textCompletion, textEdit, diff --git a/frontend/appflowy_flutter/lib/plugins/document/presentation/more/more_button.dart b/frontend/appflowy_flutter/lib/plugins/document/presentation/more/more_button.dart index 33d5d35824..016129e615 100644 --- a/frontend/appflowy_flutter/lib/plugins/document/presentation/more/more_button.dart +++ b/frontend/appflowy_flutter/lib/plugins/document/presentation/more/more_button.dart @@ -4,6 +4,7 @@ import 'package:appflowy/plugins/document/presentation/more/cubit/document_appea import 'package:appflowy/plugins/document/presentation/more/font_size_switcher.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/widget/flowy_tooltip.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -20,10 +21,15 @@ class DocumentMoreButton extends StatelessWidget { offset: const Offset(0, 30), child: FlowyTooltip( message: LocaleKeys.moreAction_moreOptions.tr(), - child: FlowySvg( - FlowySvgs.details_s, - size: const Size(18, 18), - color: Theme.of(context).iconTheme.color, + child: FlowyHover( + child: Padding( + padding: const EdgeInsets.all(6), + child: FlowySvg( + FlowySvgs.details_s, + size: const Size(18, 18), + color: Theme.of(context).iconTheme.color, + ), + ), ), ), popupBuilder: (context) { diff --git a/frontend/appflowy_flutter/lib/plugins/inline_actions/handlers/inline_page_reference.dart b/frontend/appflowy_flutter/lib/plugins/inline_actions/handlers/inline_page_reference.dart index 0904105dba..3957e903a6 100644 --- a/frontend/appflowy_flutter/lib/plugins/inline_actions/handlers/inline_page_reference.dart +++ b/frontend/appflowy_flutter/lib/plugins/inline_actions/handlers/inline_page_reference.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:appflowy/generated/locale_keys.g.dart'; +import 'package:appflowy/plugins/base/emoji/emoji_text.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart'; import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_page_block.dart'; import 'package:appflowy/plugins/inline_actions/inline_actions_result.dart'; @@ -8,6 +9,7 @@ import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy/workspace/application/view/view_service.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; class InlinePageReferenceService { InlinePageReferenceService({ @@ -83,7 +85,14 @@ class InlinePageReferenceService { final pageSelectionMenuItem = InlineActionsMenuItem( keywords: [view.name.toLowerCase()], label: view.name, - icon: (onSelected) => view.defaultIcon(), + icon: (onSelected) => view.icon.value.isNotEmpty + ? EmojiText( + emoji: view.icon.value, + fontSize: 12, + textAlign: TextAlign.center, + lineHeight: 1.3, + ) + : view.defaultIcon(), onSelected: (context, editorState, menuService, replace) async { final selection = editorState.selection; if (selection == null || !selection.isCollapsed) { diff --git a/frontend/appflowy_flutter/lib/util/either_extension.dart b/frontend/appflowy_flutter/lib/util/either_extension.dart deleted file mode 100644 index 7ec1beeb53..0000000000 --- a/frontend/appflowy_flutter/lib/util/either_extension.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:dartz/dartz.dart'; - -extension EitherX on Either { - R asRight() => (this as Right).value; - L asLeft() => (this as Left).value; -} diff --git a/frontend/appflowy_flutter/lib/util/theme_mode_extension.dart b/frontend/appflowy_flutter/lib/util/theme_mode_extension.dart index 640142912b..228339915a 100644 --- a/frontend/appflowy_flutter/lib/util/theme_mode_extension.dart +++ b/frontend/appflowy_flutter/lib/util/theme_mode_extension.dart @@ -3,16 +3,10 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; extension LabelTextPhrasing on ThemeMode { - String get labelText { - switch (this) { - case (ThemeMode.light): - return LocaleKeys.settings_appearance_themeMode_light.tr(); - case (ThemeMode.dark): - return LocaleKeys.settings_appearance_themeMode_dark.tr(); - case (ThemeMode.system): - return LocaleKeys.settings_appearance_themeMode_system.tr(); - default: - return ""; - } - } + String get labelText => switch (this) { + ThemeMode.light => LocaleKeys.settings_appearance_themeMode_light.tr(), + ThemeMode.dark => LocaleKeys.settings_appearance_themeMode_dark.tr(), + ThemeMode.system => + LocaleKeys.settings_appearance_themeMode_system.tr(), + }; } 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 a606e4eb79..ef7d015369 100644 --- a/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart +++ b/frontend/appflowy_flutter/lib/workspace/application/view/view_ext.dart @@ -7,7 +7,9 @@ import 'package:appflowy/plugins/database_view/tab_bar/tab_bar_view.dart'; import 'package:appflowy/plugins/document/document.dart'; import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/workspace/application/view/view_service.dart'; +import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; +import 'package:dartz/dartz.dart' hide id; import 'package:flutter/material.dart'; enum FlowyPlugin { @@ -15,73 +17,31 @@ enum FlowyPlugin { kanban, } -extension FlowyPluginExtension on FlowyPlugin { - String displayName() { - switch (this) { - case FlowyPlugin.editor: - return "Doc"; - case FlowyPlugin.kanban: - return "Kanban"; - default: - return ""; - } - } - - bool enable() { - switch (this) { - case FlowyPlugin.editor: - return true; - case FlowyPlugin.kanban: - return false; - default: - return false; - } - } -} - extension ViewExtension on ViewPB { - Widget renderThumbnail({Color? iconColor}) { - return const FlowySvg( - FlowySvgs.document_s, - ); - } + Widget defaultIcon() => FlowySvg( + switch (layout) { + ViewLayoutPB.Board => FlowySvgs.board_s, + ViewLayoutPB.Calendar => FlowySvgs.date_s, + ViewLayoutPB.Grid => FlowySvgs.grid_s, + ViewLayoutPB.Document => FlowySvgs.document_s, + _ => FlowySvgs.document_s, + }, + ); - Widget defaultIcon() { - return FlowySvg( - switch (layout) { - ViewLayoutPB.Board => FlowySvgs.board_s, - ViewLayoutPB.Calendar => FlowySvgs.date_s, - ViewLayoutPB.Grid => FlowySvgs.grid_s, - ViewLayoutPB.Document => FlowySvgs.document_s, - _ => FlowySvgs.document_s, - }, - ); - } - - PluginType get pluginType { - switch (layout) { - case ViewLayoutPB.Board: - return PluginType.board; - case ViewLayoutPB.Calendar: - return PluginType.calendar; - case ViewLayoutPB.Document: - return PluginType.editor; - case ViewLayoutPB.Grid: - return PluginType.grid; - } - - throw UnimplementedError; - } + PluginType get pluginType => switch (layout) { + ViewLayoutPB.Board => PluginType.board, + ViewLayoutPB.Calendar => PluginType.calendar, + ViewLayoutPB.Document => PluginType.editor, + ViewLayoutPB.Grid => PluginType.grid, + _ => throw UnimplementedError(), + }; Plugin plugin({bool listenOnViewChanged = false}) { switch (layout) { case ViewLayoutPB.Board: case ViewLayoutPB.Calendar: case ViewLayoutPB.Grid: - return DatabaseTabBarViewPlugin( - view: this, - pluginType: pluginType, - ); + return DatabaseTabBarViewPlugin(view: this, pluginType: pluginType); case ViewLayoutPB.Document: return DocumentPlugin( view: this, @@ -92,31 +52,19 @@ extension ViewExtension on ViewPB { throw UnimplementedError; } - DatabaseTabBarItemBuilder tabBarItem() { - switch (layout) { - case ViewLayoutPB.Board: - return BoardPageTabBarBuilderImpl(); - case ViewLayoutPB.Calendar: - return CalendarPageTabBarBuilderImpl(); - case ViewLayoutPB.Grid: - return DesktopGridTabBarBuilderImpl(); - default: - throw UnimplementedError; - } - } + DatabaseTabBarItemBuilder tabBarItem() => switch (layout) { + ViewLayoutPB.Board => BoardPageTabBarBuilderImpl(), + ViewLayoutPB.Calendar => CalendarPageTabBarBuilderImpl(), + ViewLayoutPB.Grid => DesktopGridTabBarBuilderImpl(), + _ => throw UnimplementedError, + }; - DatabaseTabBarItemBuilder mobileTabBarItem() { - switch (layout) { - case ViewLayoutPB.Board: - return BoardPageTabBarBuilderImpl(); - case ViewLayoutPB.Calendar: - return CalendarPageTabBarBuilderImpl(); - case ViewLayoutPB.Grid: - return MobileGridTabBarBuilderImpl(); - default: - throw UnimplementedError; - } - } + DatabaseTabBarItemBuilder mobileTabBarItem() => switch (layout) { + ViewLayoutPB.Board => BoardPageTabBarBuilderImpl(), + ViewLayoutPB.Calendar => CalendarPageTabBarBuilderImpl(), + ViewLayoutPB.Grid => MobileGridTabBarBuilderImpl(), + _ => throw UnimplementedError, + }; FlowySvgData get iconData => layout.icon; @@ -129,7 +77,8 @@ extension ViewExtension on ViewPB { final self = await ViewBackendService.getView(id); ancestors.add(self.getLeftOrNull() ?? this); } - var parent = await ViewBackendService.getView(parentViewId); + Either parent = + await ViewBackendService.getView(parentViewId); while (parent.isLeft()) { // parent is not null final view = parent.getLeftOrNull(); @@ -144,33 +93,22 @@ extension ViewExtension on ViewPB { } extension ViewLayoutExtension on ViewLayoutPB { - FlowySvgData get icon { - switch (this) { - case ViewLayoutPB.Grid: - return FlowySvgs.grid_s; - case ViewLayoutPB.Board: - return FlowySvgs.board_s; - case ViewLayoutPB.Calendar: - return FlowySvgs.date_s; - case ViewLayoutPB.Document: - return FlowySvgs.document_s; - default: - throw Exception('Unknown layout type'); - } - } + FlowySvgData get icon => switch (this) { + ViewLayoutPB.Grid => FlowySvgs.grid_s, + ViewLayoutPB.Board => FlowySvgs.board_s, + ViewLayoutPB.Calendar => FlowySvgs.date_s, + ViewLayoutPB.Document => FlowySvgs.document_s, + _ => throw Exception('Unknown layout type'), + }; - bool get isDatabaseView { - switch (this) { - case ViewLayoutPB.Grid: - case ViewLayoutPB.Board: - case ViewLayoutPB.Calendar: - return true; - case ViewLayoutPB.Document: - return false; - default: - throw Exception('Unknown layout type'); - } - } + bool get isDatabaseView => switch (this) { + ViewLayoutPB.Grid || + ViewLayoutPB.Board || + ViewLayoutPB.Calendar => + true, + ViewLayoutPB.Document => false, + _ => throw Exception('Unknown layout type'), + }; } extension ViewFinder on List { diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart index 48d611880f..4aa2435341 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/home_stack.dart @@ -10,7 +10,6 @@ import 'package:appflowy/workspace/presentation/home/toast.dart'; import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; -import 'package:flowy_infra_ui/style_widget/extension.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:provider/provider.dart'; @@ -264,7 +263,12 @@ class HomeTopBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - color: Theme.of(context).colorScheme.onSecondaryContainer, + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.onSecondaryContainer, + border: Border( + bottom: BorderSide(color: Theme.of(context).dividerColor), + ), + ), height: HomeSizes.topBarHeight, child: Padding( padding: const EdgeInsets.symmetric( @@ -286,7 +290,7 @@ class HomeTopBar extends StatelessWidget { ), ], ), - ).bottomBorder(color: Theme.of(context).dividerColor), + ), ); } } 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 a4fb78927d..2b52ce4cd4 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 @@ -370,9 +370,7 @@ class _SingleInnerViewItemState extends State { controller: controller, direction: PopoverDirection.rightWithCenterAligned, constraints: BoxConstraints.loose(const Size(360, 380)), - onClose: () => setState(() { - isIconPickerOpened = false; - }), + onClose: () => setState(() => isIconPickerOpened = false), child: GestureDetector( // prevent the tap event from being passed to the parent widget onTap: () {}, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart index 41fb826825..cc37f57c33 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart @@ -74,8 +74,6 @@ class _NotificationDialogState extends State children: [ const NotificationHubTitle(), NotificationTabBar(tabController: _controller), - // TODO(Xazin): Resolve issue with taking up - // max amount of vertical space Expanded( child: TabBarView( controller: _controller, diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/extension.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/extension.dart index 26cee376bb..cf23694078 100644 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/extension.dart +++ b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/style_widget/extension.dart @@ -1,30 +1,6 @@ import 'package:flutter/material.dart'; export 'package:styled_widget/styled_widget.dart'; -extension FlowyStyledWidget on Widget { - Widget bottomBorder({double width = 1.0, Color color = Colors.grey}) { - return DecoratedBox( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide(width: width, color: color), - ), - ), - child: this, - ); - } - - Widget topBorder({double width = 1.0, Color color = Colors.grey}) { - return DecoratedBox( - decoration: BoxDecoration( - border: Border( - top: BorderSide(width: width, color: color), - ), - ), - child: this, - ); - } -} - class TopBorder extends StatelessWidget { const TopBorder({ super.key, 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 bb9a63d720..9b0063222d 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 @@ -14,9 +14,11 @@ class FlowyText extends StatelessWidget { final bool selectable; final String? fontFamily; final List? fallbackFontFamily; + final double? lineHeight; const FlowyText( this.text, { + super.key, this.overflow = TextOverflow.clip, this.fontSize, this.fontWeight, @@ -27,11 +29,12 @@ class FlowyText extends StatelessWidget { this.selectable = false, this.fontFamily, this.fallbackFontFamily, - Key? key, - }) : super(key: key); + this.lineHeight, + }); FlowyText.small( this.text, { + super.key, this.overflow, this.color, this.textAlign, @@ -40,13 +43,13 @@ class FlowyText extends StatelessWidget { this.selectable = false, this.fontFamily, this.fallbackFontFamily, - Key? key, + this.lineHeight, }) : fontWeight = FontWeight.w400, - fontSize = (Platform.isIOS || Platform.isAndroid) ? 14 : 12, - super(key: key); + fontSize = (Platform.isIOS || Platform.isAndroid) ? 14 : 12; const FlowyText.regular( this.text, { + super.key, this.fontSize, this.overflow, this.color, @@ -56,12 +59,12 @@ class FlowyText extends StatelessWidget { this.selectable = false, this.fontFamily, this.fallbackFontFamily, - Key? key, - }) : fontWeight = FontWeight.w400, - super(key: key); + this.lineHeight, + }) : fontWeight = FontWeight.w400; const FlowyText.medium( this.text, { + super.key, this.fontSize, this.overflow, this.color, @@ -71,12 +74,12 @@ class FlowyText extends StatelessWidget { this.selectable = false, this.fontFamily, this.fallbackFontFamily, - Key? key, - }) : fontWeight = FontWeight.w500, - super(key: key); + this.lineHeight, + }) : fontWeight = FontWeight.w500; const FlowyText.semibold( this.text, { + super.key, this.fontSize, this.overflow, this.color, @@ -86,13 +89,13 @@ class FlowyText extends StatelessWidget { this.selectable = false, this.fontFamily, this.fallbackFontFamily, - Key? key, - }) : fontWeight = FontWeight.w600, - super(key: key); + this.lineHeight, + }) : fontWeight = FontWeight.w600; // Some emojis are not supported on Linux and Android, fallback to noto color emoji const FlowyText.emoji( this.text, { + super.key, this.fontSize, this.overflow, this.color, @@ -100,11 +103,10 @@ class FlowyText extends StatelessWidget { this.maxLines = 1, this.decoration, this.selectable = false, - Key? key, + this.lineHeight, }) : fontWeight = FontWeight.w400, fontFamily = 'noto color emoji', - fallbackFontFamily = null, - super(key: key); + fallbackFontFamily = null; @override Widget build(BuildContext context) { @@ -120,6 +122,7 @@ class FlowyText extends StatelessWidget { decoration: decoration, fontFamily: fontFamily, fontFamilyFallback: fallbackFontFamily, + height: lineHeight, ), ); } else { @@ -135,6 +138,7 @@ class FlowyText extends StatelessWidget { decoration: decoration, fontFamily: fontFamily, fontFamilyFallback: fallbackFontFamily, + height: lineHeight, ), ); } diff --git a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/clickable_extension.dart b/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/clickable_extension.dart deleted file mode 100644 index 267913fe9a..0000000000 --- a/frontend/appflowy_flutter/packages/flowy_infra_ui/lib/widget/clickable_extension.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:flutter/material.dart'; - -extension ClickableExtensions on Widget { - Widget clickable(void Function() action, {bool opaque = true}) { - return GestureDetector( - behavior: opaque ? HitTestBehavior.opaque : HitTestBehavior.deferToChild, - onTap: action, - child: MouseRegion( - cursor: SystemMouseCursors.click, - opaque: opaque, - child: this, - ), - ); - } -} diff --git a/frontend/resources/translations/en.json b/frontend/resources/translations/en.json index 3a287bfe5e..fd32b8fb39 100644 --- a/frontend/resources/translations/en.json +++ b/frontend/resources/translations/en.json @@ -779,6 +779,9 @@ "label": "Embed link", "placeholder": "Paste or type an image link" }, + "unsplash": { + "label": "Unsplash" + }, "searchForAnImage": "Search for an image", "pleaseInputYourOpenAIKey": "please input your OpenAI key in Settings page", "pleaseInputYourStabilityAIKey": "please input your Stability AI key in Settings page", @@ -828,6 +831,7 @@ "renameGroupTooltip": "Press to rename group", "createNewColumn": "Add a new group", "addToColumnTopTooltip": "Add a new card at the top", + "addToColumnBottomTooltip": "Add a new card at the bottom", "renameColumn": "Rename", "hideColumn": "Hide", "groupActions": "Group Actions", @@ -854,6 +858,7 @@ "ungroupedItemsTitle": "Click to add to the board", "groupBy": "Group by", "referencedBoardPrefix": "View of", + "notesTooltip": "Notes inside", "mobile": { "editURL": "Edit URL", "unhideGroup": "Unhide group",